Bạn phải di trú các mảng kết hợp vào varray hoặc nested table trước khi sử dụng các toán tử tập hợp, và các tập hợp collection phải chứa các kiểu đữ liệu SQL vô hướng.. Bạn sẽ đưa ra một
Trang 1oecevecce
Thi thuat
Các mắng kết hgp (associative array) không có cú pháp định hướng tương đương
với cú pháp cùng tên với chúng trong JavaScript Bạn không thể xem mắng kết
hợp là một cursor bằng cách sử dụng một cấu trúc vòng lặp FOR cursor Điều này đưa ra một vấn để Một gid tri index không phải số đòi hỏi bạn phải biết nơi bắt đầu và cách tăng lượng Các phương thức Collec- tion API FIRST và NEXT cung cấp những công cụ Chi tiết về Collection API được để cập sau trong chương này nếu bạn muốn biết thêm về những phương thức này bây giờ
Bạn có thể sử dụng phương pháp được minh họa trong chương trình mẫu sau đây để giải quyết vấn đề Trong vòng lặp FOR dãy thứ hai, logic
để truyền ngang một index chuỗi duy nhất được cung cấp:
This is found in create_assocarray6.sql on the publisher's web site
DECLARE
Define variables to traverse a string indexed associative array
current VARCHAR2(9 CHAR);
element INTEGER;
Define required collection datatypes
TYPE months_varray I$ VARRAY(12) OF STRING(9 CHAR):
TYPE calendar_table |S TABLE OF VARCHAR2(9 CHAR) INDEX BY VARCHAR2(9 CHAR);
- Declare a varray
month MONTHS_VARRAY :=
months_varray(‘January’, ‘February’, 'March’,'April',‘May’,'June’
‘July’, August’, September’, ‘October’ ,/November','December’);
Declare empty associative array
Trang 2Check if next index value exists
tF catendar.NEXT(current) IS NOT NULL THEN
Assign the character index to a variable
Print an indexed element from the array
4 DBMS_OUTPUT.PUT_LINE(‘Index (‘| | current 11 '] is [' ! | element t 1 END LOOP;
END IF;
Trang 3Ví dụ trước minh họa việc đi chuyển nội dung của một varray có index
số sang một mảng kết hợp có index chuỗi duy nhất
Câu lệnh IF kiểm tra xem bộ đếm vòng lặp for dãy có bằng 1 hay không Câu lệnh này tìm record đầu tiên để bắt đầu truyền ngang mảng kết hợp Bạn sử dụng phương thức Collection API FIRST để trả về giá trị index chuỗi duy nhất đâu tiên Chương trình gan gid tri index chudi duy nhất sang biến current và sau đó nó sử dụng biến current dé tìm giá trị đữ liệu rêi gán vào biến element Vào lúc này, nó thoát câu lệnh if- then-else và in các giá trị như được mô tả sau đó
Vào bước đi thứ hai qua vòng lặp FOR dãy, cuộc kiểm tra câu lệnh IF
sẽ thất bại Sau đó, nó sẽ đi đến câu lệnh ELSE và gặp phải câu lệnh ïf- then-else được xếp lổng Câu lệnh IF sử dụng Collection API NEXT để kiểm tra xem có một record khác trong máng kết hợp hay không Nếu có một record khác trong mảng kết hợp, nó sẽ sử dụng biến current để tìm giá trị index kế tiếp Nó gán giá trị để thay thế giá trị trong biến
current Khi không còn có các record nữa, nó thoát
Nó in các index và giá trị từ mảng kết hợp calendar bằng package DBMS_ OUTPUT Chương trình tạo luồng đầu ra sau đây Lần nữa, nó
đã được chỉnh sửa để bảo toàn khoảng trống:
This is found running create_assocarray6.sqt from the publisher's web
Trang 4phụ thuộc vào các tham số cơ sở dữ liệu NLS_COMP và NLS SORT
trong cdc co sé di liệu được toàn cầu hóa
liết quả của hành vì phân loại này, các giá trị index chuỗi duy nhất đưa ra một số vấn để thú vị cần xem xét Nếu bạn cần theo đối thứ tự gốc, bạn sẽ cần sử dụng một record hoặc loại đối tượng cung cấp một khóa đại điện Khóa đại điện có thể duy trì thứ tự gốc
Các toán tử tập hợp
Oracle 11g cung cấp các toán tử tập hợp Chúng hành động và có chức năng như các toán tử tập hợp SQL trong các câu lệnh select Sự khác biệt là chúng được sử dụng trong các phép gán giữa những tập hợp của các loại chữ ký tương hợp Chúng chỉ làm việc với các varray và các nested table bởi vì chúng đòi hỏi các giá trị index số Bạn phải di trú các mảng kết hợp vào varray hoặc nested table trước khi sử dụng các toán tử tập hợp, và các tập hợp (collection) phải chứa các kiểu đữ liệu SQL vô hướng Bạn sẽ đưa ra một số sai hoặc các loại lỗi đối số hoặc một ngoại
lệ PL8-00306, nếu bạn sử dụng các toán tử tập hợp để so sánh các tập hợp của các loại đối tượng do người dùng định nghĩa Bảng 7.2 mô tả các toán tử đa tập hợp
Bảng 7.2 Các toán tử tập hợp cho các lập hợp (Collections)
Toán tử đa tập hợp Mô tả
CARDINALITY 'Toán tử CARDINALITY đếm số các phần
tử trong một tập hợp Nó không cố gắng đếm chỉ các phần tử duy nhất, nhưng bạn
có thể kết hợp nó với toán tử SET để đếm những phần tử duy nhất Nguyên mẫu là:
CARDINALTTY(collection)
toán hạng khi bạn kiểm tra xem một biến
có rỗng hoặc không rỗng Cú pháp so sánh là:
variable_name IS [NOT] EMPTY
Trang 5Toán tử MEMBER OF cho bạn kiểm tra
xem toán hạng trái có phải là một thành viên của tập hợp được sử dụng làm toán shang phải hay không Cú pháp so sánh
là:
collection_name Toán tử MULTISET EXCEPT loại bỏ một
tập hợp ra khối một tập hợp khác Nó làm việc như toán tit tap hop SQL MINUS
Nguyên mẫu là:
collection MULTISET EXCEPT collection
Todn tit MULTISET INTERSECT luong
giá hai tập hợp và trả về một tập hợp Tập hợp trả về chứa những phần tử vốn
đã được tìm thấy trong cả hai tập hợp gốc Nó làm việc như toán tứ tập hợp SQL INTERSECT Nguyên mẫu là;
collection MULTISET INTERSECT collec-
tion
Toén tt) MULTISET UNION luong gid hai
tập hợp và trả về một tập hợp Tập hợp trả về chứa tất cả phần tử của cả hai tập hợp Nơi các phần tử trùng lặp được tìm thấy, chúng được trả về Nó có chức năng
như toán tử tập hgp SQL UNION ALL
Bạn có thể sử dụng toán tử DISTINCT để loại bỏ các phẩn tử trùng lặp Toán tử DISTINCT tuân theo quy tắc toán tử
MULTISET UNION Nó có chức năng như
toán tử SQL UNION Nguyên mẫu là: collection MULTISET UNION collection
Toán tử SET loại bỏ các phần tử trùng lặp
ra khỏi một tập hợp, và do đó tạo một tập hợp giá trị duy nhất Nó hoạt động như
một toán tử DISTINCT phân loại ra các
phần tử trùng lặp trong một câu lệnh SQL Nguyên mẫu sử dụng là:
SET(collection) Bạn cũng có thể sử dụng toán tử SET làm một toán hạng khi bạn kiểm tra xem một
Trang 6Chương 7: Các tập hợp
SUBMULTISET
323 biến rỗng hay không rỗng Cú pháp so sánh là:
Variable_name IS [NOT] A SET
"Toán tử SUBMULTISET nhận dang xem một tập hợp có phải là một tập hợp con của một tập hợp khác hay không Nó trả
về true khi toán hạng trái là một tập hợp con của toán hạng phải True có thể gây nhầm lẫn nếu bạn tìm một tập hợp con phù hợp vốn tốt thiểu chứa ít hơn tập hợp
bố (superset) một phần tử Hàm trả về true bởi vì bất kỳ tập hợp là một tập hợp
con của chính nó Không có phép thử cho một tập hợp con thích hợp nếu cũng không
sử dụng toán tứ CARDINALITY để so sánh xem số lượng phần tử của cả hai tập hợp không bằng hay không
Nguyên mẫu là:
collection SUBMULTISET OF collection Các tập hợp được hiển thị dưới dạng những đanh sách giá trị được phân cách bằng dấu phẩy Loại nested table và hàm SQL sau đây cho bạn định dạng kết quả của các toán tử tập hợp thành một tập hợp được phân cách bằng dấu phẩy
=> This is feund in multiset.sq! on the puhlisher's web site
CREATE OR REPLACE TYPE list IS TABLE OF NUMBER;
ELSE Anything not null or empty
FOR i IN set_in.FIRST set_in.LAST LOOP
IF i = set_in.FIRST THEN
IF set_in.COUNT = 1 THEN retval := '(' | | set_in(i) 1 1 ')';
Trang 7ELSE
retval := '{' | | set_in(i);
ENO IF; ELSIF i <> set_in.LAST THEN
retval ;= retval | |‘, ‘| | set_in(i);
Teán tử EÄRDINALITY
Toán tử CARDINALITY cho phép đếm các phần tử trong một tập hợp Nếu có các phân tử duy nhất, chúng được đếm một lân cho mỗi bản sao trong tập hợp Ví dụ sau đây trình bày cách loại trừ các phần tử tương hợp:
Trang 8Chương 7: Các tập hợp 325
}
Bây giờ chương trình in số 4 bởi vi có bốn phần tử duy nhất trong tập hợp được dẫn xuất từ tập hợp phần tử thứ sáu Phân này đã minh họa cách bạn có thể sử dụng toán tử CARDINALITY để đếm các phần tử hoặc tập hợp
Todu ti MULTISET INTERSECT
Toán tử MULTISET INTERSECT cho phép tìm những phần tử còn lại từ tập hợp đầu tiên sau khi loại bỏ bất kỳ phần tử tương hợp ra khỏi tập hợp thứ hai Toán tử bổ qua bất kỳ phần tử trong tập hợp thứ hai không được tìm thấy trong tập hợp thứ nhất Ví dụ sau đây trình bày cách loại trừ các phần tử tương hợp:
DECLARE
a LIST := list(t,2,3,4);
b LIST := list(4,5,6,7);
BEGIN
Trang 9dbms_output.put, line(format_list(a MULTISET EXCEPT b));
END;
Chỉ phần tử 4 hiện hữu trong cả hai tập hợp Do đó phép toán loại bỏ
4 ra khỏi tập hợp thứ nhất Kết quả sau đây được tạo ra bởi khối:
(1, 2, 3)
Phần này đã trình bày cách bạn có thể sử dụng các toán tử tập hợp (set operator) để loại trừ những phần tử ra khói một tập hợp khi chúng nằm trong một tập hợp khác
Tsấn tử MULTISET INTERSECT
Toán tử MULTISET UNION cho bạn tìm giao hoặc những giá trị tương hợp giữa hai tập hợp Ví dụ sau đây trình bày cách tạo một tập hợp của giao giữa hai tập hợp
Toda til MULTISET UNION
Toán tử MULTISET UNION thực thi một phép toán UNION ALL trên cả hai tập hợp Ví dụ sau đây trình bày cách kết hợp các tập hợp thành một tập hợp:
DECLARE
a LIST := list(1,2,3,4);
b LIST ‘= list(4,5,6,7);
BEGIN
Trang 10
(1, 2, 3, 4, 4, 5, 6, 7)
Bạn sẽ thấy cả hai tập hợp chứa số nguyên 4 và tập hợp vừa tạo ra có hai bản sao của nó Bạn có thể loại bỏ việc sao chép và mô phỏng một toán tử UNION bang cách thêm wizard DISTINCT:
Trang 11Toán tử $ET
Toán tử SET hành động trên một đầu ra vốn là một tập hợp khác, nó loại bỏ bất kỳ bản sao ra khỏi tập hợp và trả về một tập hợp mới có những giá trị duy nhất Ví dụ sau đây minh họa cách xén một tập hợp thành các phần tứ duy nhất:
IF set_in IS A SET THEN
IF set_in IS NOT EMPTY THEN
RETURN ‘Yes - a unique collection.’;
ELSE RETURN ‘Yes - an empty collection.';
Trang 12Chương 7: Các tập hop 329
BEGIN
dbms_output.put_tine(isset(a}) dbms_output.put_line{isset(b)) dbms_output.put_line(isset(c))
END;
/
Hau ghí nhớ sử dụng các dấu ngoặc đón trống khi bạn xâu dựng các lập hợp tông ếu bọn quên các dấu ngoạc đơn bởi vì bạn không cần chúng qọi mội số hàm hoặc thủ lục, bạn sẽ đưa ca một lõi OĐBÁ-OO33O - invalid use of type name (sử dụng lên kiểu không hợp lệ)
Chương trình trả về
Yes - a unique collection
No - a non-unique collection
Yes - an empty collection
Khối nặc danh này cho thấy phép so sánh I8 A SET trả về true khi tập hợp duy nhất hoặc rỗng Bạn phải sử dụng phép so sánh I8 EMPTY
để bắt giữ các tập hợp rỗng như đã làm trong hàm format_set được minh họa trước đó
Phần này đã trình bày cách bạn có thể sử dụng các toán tử tập hợp để tạo những tập hợp của giao giữa hai tập hợp
Ttấn tử $UBMULTISET
Toán tử SUBMUL/TISET so sánh toán hạng trái với toán hạng phải
để quyết định xem toán hạng trái có phải là một tập hợp con của toán hạng phải hay không Nó trả về một giá trị Boolean true khi nó tìm thấy tất cả phần tử trong tập hợp trái cũng nằm trong tập hợp phải
Ví dụ sau đây minh họa cách quyết định xem một tập hợp có phải là một tập hợp con của một tập hợp khác hay không:
Trang 13sự Một tập hợp con thật sự khác biệt bởi vì tối thiểu nó chứa ít hơn tập hợp một phần tử
Những phương thức Collection API thật sự không phải là những phương thức theo một nghĩa hướng đối tượng thật sự Chúng là các hàm và thủ tuc EXTEND, TRIM va DELETE là những thủ tục Các phương thức còn lại là các hàm
Bảng 7.3 tóm tắt Oracle 11g Collection API
Bang 7.3 Oracle 11g Collection API
Phương thức Mô tả
COUT Phương thức COUNT trả về số phân tử có
không gian cấp phát trong các kiểu dữ liệu
Trang 14` thức COUNT có thể nhỏ hơn giá trị trả về của LIMIT cho những kiểu đữ liệu VARRAY Nó có nguyên mẫu sau đây: pis_integer COUNT
Phương thức DELETE cho bạn xóa những thành viên ra khỏi tập hợp Nó có hai
tham số hình thức; một là bắt buộc và cái
kia thì tùy chọn Cả hai tham số chấp nhận
các kiểu biến PLS_TNTEGER, VARCHAR2
và LONG Chỉ một tham số thật sự, n được hiểu là giá trị index để xóa ra khỏi tập hợp Khi bạn cung cấp hai tham số thật
sự, hàm xóa mọi thứ ra khỏi tham số n đến m Nó có những nguyên mẫu sau đây: void DELETE (n)
void DELETE (n, m) Phương thức EXISTS kiểm tra để tìm một, phân tử có index được cung cấp trong một tập hợp Nó trả về true khi phần tử được tìm thấy nếu không nó trả về false Phần
tử có thể chứa một giá trị hoặc một giá trị rỗng Nó có một tham số bắt buộc, và tham
số có thể là một kiểu PLS INTEGER, VARCHAR2 hoặc LONG Nó có nguyên mẫu sau đây:
boolean EXISTS (n) Phuong thức EXTEND cấp phát không gian cho một hoặc nhiều phần tử mới trong
một tập hợp VARRAY hoặc NESTED
TABLE Nó có hai tham số tùy chọn Nó thêm không gian cho một phần tử theo mặc định mà không có bất kỳ tham số thật sự Một toán tử tùy chọn chỉ định bao nhiêu không gian vật lý sẽ được cấp phát
nhưng nó bị ràng buộc bởi giá trị LIMIT
cho các kiểu dữ liệu VARRAY Khi hai tham số tùy chọn được cung cấp, tham số thứ nhất chỉ định bao nhiêu phần tử nên được cấp phát không gian và tham số thứ hai chỉ định index mà nó sẽ sử dụng để sao chép giá trị sang không gian mới được
Trang 15Phương thức FIRST trả về giá trị subscript (chỉ số đưới) thấp nhất trong một tập hợp
Nó có thể trả về một kiểu PLS_INTEGER, VARCHAR2 hoặc LONG Nó có nguyên
mẫu sau đây:
mixed FIRST Phương thức LAST tra vé gid trị chỉ số dưới cao nhất trong một tập hợp Nó có thể trả về một kiểu PLS_INTEGER,
VARCHAR2 hoặc LONG Nó có nguyên
mẫu sau đây:
mixed LAST Phương thức LIMIT trả về giá trị chỉ số dưới cao nhất có thể có trong một tập hợp
Nó chỉ có thể trả về một kiểu PLS INTEGER và chỉ có thể trả về một
kiểu PLS_INTEGER và chỉ có thể được sử
dụng bởi một kiểu dữ liệu VARRAY Nó có nguyên mẫu sau đây:
mixed LIMIT Phương thức NEXT trả về giá trị chỉ số dưới cao nhất kế tiếp trong một tập hợp
khi thành công hoặc một giá trị false Giá trị trả về là một kiểu PLS_INTEGER, VARGHAR2 hoặc LONG Nó đòi hỏi một
giá trị index hợp lệ dưới dạng một tham
số thật sy N6 có nguyên mẫu sau đây: mixed NEXT (n)
Phương thức PRIOR trả về giá trị chỉ số
đưới thấp hơn kế tiếp trong một tập hợp khi thành công hoặc một giá trị false Giá
trị trả về là một kiểu PLS_INTEGER, VARCHAR2 hoặc LONG Nó đòi hỏi một
giá trị iadex hợp lệ đưới dạng một tham
số thật sự Nó có nguyên mẫu sau đây: mixed PRIOR (n)
Trang 16đây:
void TRIM void TRIM (n) Bạn sẽ kiểm tra từng phương thức trong thứ tự bảng chữ cái Một số
ví dụ bao gồm nhiều phương thức Collection API Như trong các loại tập hợp được đề cập, khó xử lý tách biệt các phương thức Collection API Nơi một ví dụ để cập đầy đủ nhiều phương thức, nó sẽ được tham chiếu chéo Đôi khi nó có thể được tham chiếu trước Bên dưới mỗi phương thức ollection API, bạn sẽ được chuyển đến mã mẫu thích hợp Bạn sẽ kiểm tra từng phương thức Collection API trong các chương trình mẫu Nên chú ý rằng chỉ phương thức EXISTS sẽ không đưa ra một ngoại lệ nếu tập hợp rỗng
Có năm ngoại lệ tập hợp chuẩn được mô tả trong bảng 7.4
Một nỗ lực nhằm sử dụng một chỉ số dưới (subscript) vốn đã bị xóa hoặc nó là một giá trị index chuỗi duy nhất không tổn tại trong một mảng kết hợp
Một nỗ lực nhằm sử dụng một giá trị index số cao hơn giá trị số tối đa hiện hành Lỗi này áp dụng chỉ vào các varray
và nested table Các mảng kết hợp (asso- cỉative array) không được liên kết bởi giá trị trả về COUNT khi thêm các phần tử mới
Một nỗ lực nhằm sử dụng một giá trị index số bên ngoài giá trị trả về LIMTT Lỗi này chỉ áp dụng vào các varray và
nested tables Giá trị LIMIT được định nghĩa một trong hai cách Varray xác lập
kích cỡ tối đa vốn trở thành giá trị giới
Trang 17hạn của chúng Các nested table và asso-
ciative array không có kích cỡ tối đa cố
định, do đó giá trị giới hạn được xác lập
bởi không gian được cấp phát bởi phương thie EXTEND
VALUE_ERROR Một nỗ lực nhằm sử dụng một kiểu vốn
không được chuyển đổi thành một PLS_INTEGER vốn là kiểu dữ liệu cho các chỉ số dưới đạng số
Puớng thức COUNT
Phương thức COUNT thật sự là một hàm Nó không có danh sách tham số hình thức Nó trả về số phần tử trong mảng Chương trình mẫu sau đây minh họa rằng nó trả về một giá trị PLS_INTEGER:
DECLARE
TYPE number_table IS TABLE OF INTEGER;
number_tist NUMBER_TABLE := number_table(1,2,3,4,5);
How many elements? [5]
Phudag thie BELETE
Phương thức DELETE là một thủ tục Nó là một thủ tục quá tải Nếu khái niệm về quá tải (overload) mới đối với bạn, hãy xem chương 9
Nó có một phiên bản lấy một tham số hình thức Tham số phải là một giá trị chỉ số dưới hợp lệ trong tập hợp Phiên bản này sẽ loại bổ phần tử
có chỉ số đó Nó được minh họa trong chương trình mẫu của phương thức EXISTS
Phiên bản còn lại lấy hai tham số hình thức Cả hai tham số phải là các giá trị chỉ số dưới hợp lệ trong tập hợp Phiên bản này xóa một dãy phần tử bao hàm gần kể ra khéi một tập hợp Chương trình mẫu sau đây mình họa việc xóa dãy ra khỏi một tập hợp:
DECLARE
TYPE number_table S TABLE OF INTEGER;