Lời NÓI ĐẦU "Giáo trình Hướng dẫn Lý thuyết và kèm theo bài tập thực hành ORACLE 11g" được biên soạn toàn điện từ đầu đến cuối nhằm mục đích giúp bạn đọc làm quen với ngôn ngữ lập trình
Trang 1Th.S NGUYỄN QUẢNG NINH - NGUYỄN NAM THUẬN
Trang 2Th.S: NGUYỄN QUẢNG NINH- NGUYEN NAM THUAN
Trang 3Lời NÓI ĐẦU
"Giáo trình Hướng dẫn Lý thuyết và kèm theo bài tập thực hành ORACLE 11g" được biên soạn toàn điện từ đầu đến cuối nhằm mục đích giúp bạn đọc làm quen với ngôn ngữ lập trình PL/SQL, nắm vững các điểm cơ bản của ngôn ngữ và các kỹ thuật lập trình nâng cao để có thể phát triển các ứng dụng PL/SQL mạnh được điều khiển bởi cơ sở dữ liệu, giúp
nhanh chóng hoàn thành các dự án phát triển của các cá nhân, công ty và doanh nghiệp
Sách gồm 2 tập, được thiết kế thành các phần chính sau
đây:
Phén 1: Các điểm cơ bản vé PL/SQL
Phần này giới thiệu các tính năng Oracle Database 10g phiên bản 2 gần đây và các tính năng Oracle Database 11g mới, trình bày các điểm cơ bản của PL/SQL, và giải thích các
khái niệm về ngữ nghĩa, các kiểu dữ liệu, các cấu trúc điều
khiển và sự quản lý lỗi
Phân II: Lập trình PLISQL
Phần này trình bày cách sử dụng các công cụ mạnh để
phát triển các ứng dụng cơ sở dữ liệu phù hợp nhu cầu thực tế
và mang lại hiệu quả ứng dụng cao, bao gồm các hàm và thủ tục, các tập hợp, các gói, các bộ kích khởi (trigger) và các đối tượng lớn Oracle
Phén III: Lap trinh nang cao PL/SQL
Với phần này, bạn đọc sẽ được hướng dẫn về SQL động, sự liên kết giữa các phiên làm việc, các thủ tục ngoài, các loại đối tượng, các thư viện Java và sự phát triển ứng dụng Web nhằm đạt được các kỹ thuật lập trình nâng cao với PL/SQL
Sách được bố cục rõ ràng theo từng chủ điểm cụ thể, nội
dung trình bày ngắn gọn, hy vọng sẽ là một tài liệu tham
khảo thật sự hữu ích cho bạn đọc, đặc biệt là ở lĩnh vực lập trình cơ sở dữ liệu
Rất mong đón nhận sự đóng góp ý kiến chân thành từ bạn đọc về một số sai sót khó tránh khỏi trong quá trình biên
soạn nhằm làm cho sách hoàn thiện hơn Xin chân thành cảm ơn
Tac gia
Trang 4Chương 8: Các đối tượng lớn
PHỒN IW /⁄2 4+ ⁄27/
Lập trình PUSOL
Chương 8: Các đối tượng lớn
Chương 9: Các gói (Package)
Phương 10: Các Trigger
Trang 58 Chương 8: Các đối tượng lớn
CÁC đổi Tượng lớn
phép lưu trữ text, hình ảnh, nhạc và video trong cơ sở đữ liệu
Oracle 11g thay đổi đáng kể bức tranh LOB bằng cách tái
thiết kế cách làm việc của các đối tượng lớn (arge object) Bây giờ chúng
C ác đối tượng lớn (LOB) là những cấu trúc dữ liệu mạnh mẽ cho
nhanh hơn và an toàn hơn (SecureFiles) Bạn có thể định nghĩa các cột BLOB, CLOB hoặc NCLOB dưới dạng các SecureFiles khi bạn tạo một
table (bảng) hoặc thay đổi nó
Các LOB có thể chứa tối đa 8 đến 128 terabytes, phụ thuộc vào cách bạn cấu hình cơ sở đữ liệu Một lệnh gọi đến hàm GET_STORAGE_LIMIT trong gói (package) DBMS_LOB cho biết kích cỡ LOB tối đa của cơ sở dữ
liệu Bạn có thể lưu trữ các đối tượng lớn ký tự trong các cột CLOB và các đối tượng lớn nhị phân (binary) bên trong cơ sở đữ liệu đưới đạng các cột BLOB hoặc bên ngoài cơ sở div liệu dưới dạng cột BFILE (binary file) Các cột BFILE luu tra một locator tré sang vị trí vật lý của một file bên ngoài
Chương này giải thích cách sử dụng PL/SQL để làm việc với các kiểu
dữ liệu LOB khác nhau Chương bao gồm những chủ điểm sau đây:
§ Các đối tượng lớn ký tự
PL/SQL đọc các file và ghỉ các cột CLOB hoặc NCLOB
Úpload các CLOB lên cơ sở dữ liệu
Các đối tượng lớn nhị phân
PL/SQL đọc các file và ghi các cột BLOB
Upload các BLOB lên cơ sở dữ liệu
SecureFiles
Trang 6Chương 8: Các đối tượng lớn 9
mã Tao và sử dụng các thư mục ảo (virtual directories)
m Gói DBMS_LOB
Những khái niệm chỉ phối cách sử dụng các kiểu dữ liệu BLOB, CLOB,
và NCLOB thì rất tương tự Các kiểu đữ liệu CLOB và NCLOB được đề
cập trước tiên vì chúng cho bạn tập trung vào việc quản lý các giao tác
với các khối text lớn Kiểu dữ liệu BLOB đứng thứ hai bởi vì những khái
niệm thúc đẩy cho các đối tượng lớn ký tự (character) Các BLOB lưu trữ các tài liệu nhị phân (binary), như các ñle Adobe PDE (Portable Docu- ment Format), anh va phim (movie) bên trong cơ sở dữ liệu Việc truy
cập và hiển thị các ñle BLOB được bổ sung bằng cách sử dụng ngôn ngữ
lập trình PHP để kết xuất các ảnh trong các trang web SecureFiles tuân
theo các kiểu đữ liệu bình thường và được lưu trữ bên trong bởi vì chúng
thêm những tính năng vào các CLOB
Sau SecureFiles, bạn học cách xác lập, cấu hình, đọc và duy trì các
kiểu dữ liệu BEILE Chúng đồi hỏi thêm nỗ lực trong một số cách bởi vì
catalog chỉ lưu trữ đữ liệu locator, và bạn phải bảo đảm sự hiện diện vật
lý của chúng trong hệ thống ñle Gói DBMS_LOB đứng sau cùng bởi vì không phải hàm nào cũng cần thiết để hướng dẫn cách sử dụng các đối
tượng lớn Mỗi phần dựa vào một phần trước nó, nhưng bạn cũng có thể
sử dụng chúng riêng lẻ để tham khảo nhanh
Các kiểu đữ liệu CLUOB và NCLOB định nghĩa một cột trong một table
hoặc nested table Nó có kích cỡ vật lý tối đa giữa 8 và 128 terabytes Kiểu dữ liệu CLOB cho péep lưu trữ các file text lớn File text có thể phục
vụ nhiều mục đích, chẳng hạn như một chương trong sách, một quyển sách trong thư viện hoặc một đoạn XML Mục này xem xét text như là một đơn vị làm việc
Cột CLOB thường được lưu trữ riêng biệt với phần còn lại của hàng
trong một table Chỉ descriptor hoặc locator được lưu trữ vật lý trong cột Locator trồ sang nơi nội dung vật lý của một CLOB được lưu trữ và cung
cấp một tham chiếu dẫn đến vùng làm việc riêng trong SGA Ving lam
việc này cho phép cuộn qua nội dung và ghỉ các cụm đữ liệu mới Một số nội dung tham khảo sử dụng thuật ngữ descriptor để nói đến locator (bộ
định vị) BLOB, CLOB và NCLOB, nhưng sử dụng locator khi làm việc
với các BEILE ngoài Tài liệu Oraele 11g bắt đầu gọi cả hai là các locator
một cách nhất quán.
Trang 710 Chương 8: Các đối tượng lớn
Kiểu dữ liệu CLOB là một loại đối tượng Là loại đối tượng nên nó đòi hỏi xây dựng một instance đối tượng một cách ngầm định hoặc tường mỉnh Bạn có thể xây đựng một biến CLOB ngầm định bằng cách gán trực tiếp một số hoặc loại ký tự Khi bạn gán một số vào một kiểu đữ liệu
CLOB, đầu tiên số được cast (gán) vào một kiểu dữ liệu ký tự và sau đó kiểu dữ liệu ký tự được chuyển đổi thành kiểu dữ liệu CLOB Thật không may, các chuyển đổi ký tự cho các kiểu đữ liệu CHAR, NCHAR
NVARCHAR và VARCHAR2 bị ràng buộc bởi môi trường SQL hoặc PL/ SQL SQL cho phép chuyển đổi các luồng ký tự lên đến 4.000 bytes,
trong khi PL/SQL cho phép chuyển đổi 32.767 bytes dữ liệu ký tự cùng
var2 CLOB := ‘some_string’; Declare a CLOB with a string literal
Các cột CLOB khác với các kiểu đữ liệu vô hướng bởi vì chúng không
giới hạn chỉ trong các trạng thái NULL hoặc NOT NULL Các BLOB,
CLOB và NCLOB thì NULL, rỗng (empty), hoặc được tập hợp (popu-
lated) như được trình bày trong bảng 8.1
Bạn chèn một CLOB hoặc NGLOB rỗng bằng cách gọi phương thức
tạo empty_clobQ dưới dạng một biểu thức trong mệnh đề VALUES của
một câu lệnh INSERT Sự thay đổi duy nhất cho các kiểu đữ liệu BLOB
là việc thay thế phương thức tạo empty_blobQ
Câu lệnh sau đây chèn một phương thức tạo empty_clobQ trong cột item_ desc của table item:
This is found in create_store.sq! on the publisher's web site
INSERT INTO item VALUES
( item_s1.nextval
, ‘ASIN: BOO003CXI1'
» (SELECT common_lookup_id
FROM common_lookup
WHERE common_lookup_type = ‘DVD_WIDE_SCREEN’)
, ‘Harry Potter and the Sorcer''s Stone’
, ‘Two-Disc Special Edition’
, @mpty_clob()
; NULL,'PG','MPAA','28-MAY-2002'
, 8, SYSDATE, 3, SYSDATE);
Trang 8Chương 8: Các đối tượng lớn 11
Ngay khi đã chèn một CLOB rỗng, bạn có thể cập nhật nó bằng nhiều cách Một sự cập nhật cơ bản sử dụng SQL giới hạn bạn chỉ trong chuỗi 4.000 bytes Sau đây là một câu lệnh SQL mẫu:
UPDATE item
SET item dese = ‘Harry Potter is seemingly an ordinary eleven-year-old
boy, ' WHERE item_title = ‘Harry Potter and the Sorcererˆs Stone’
AND _ item_type IN
(SELECT common_lookup_id FROM common_lookup WHERE common_lookup_table = ‘ITEM’
AND common_lookup_column = 'ITEM_TYPE' AND REGEXP_LIKE(common_lookup_type,'*(DVDIVHS)*'))
Bang 8.1 Cac trang thai dit ligu BLOB, CLOB va NCLOB Trang thai Mô tả
NULL Cột trong một hàng table chứa một giá trị
NCLOB rỗng
Populated Cột chứa một locator LOB và một lệnh
gọi đến hàm DBM8_LOB.GETLENGTH
trả về một giá trị số nguyên dương cho
một cột BLOB, CLOB hoặc NCLOB
Câu lệnh UPDATE xác lập cột item _desc bằng với một chuỗi nhỏ hơn
4.000 bytes Subquery trên table common_]ookup sử dụng một biểu thức thông thường để tìm tất cả cột common_lookup_type bắt đâu với chữ hoa
DVD hoặc VHS
Nếu bạn chuyển câu lệnh UPDATE đến bên trong một khối PL/SQL,
bạn có thể gán một chuỗi 32.767 bytes vào cột CLOB Tuy nhiên, sau đó bạn phải sử dụng thủ tục WRITEAPPEND từ gói DBMS_LOB để bổ sung
thêm dữ liệu vào cột sau lần ghi ban đâu Phương pháp này có lẽ dễ nhất
và có sẵn rộng rãi nhất trong đoạn mã PL/SQL trên web ghi một cột CLOB Giải pháp sử dụng gói DBMS_LOB để đọc một file Sau đó, nó tải
dữ liệu sang các cụm 32.767 bytes qua thủ tục
DBMS_LOB.WRITEAPPEND
Trang 912 Chương 8: Các đối tượng lớn
Vấn để với phương pháp này là nó không tận dụng mệnh đề RE-
TURNING INTO mà bạn có thể thêm vào các câu lệnh DML INSERT ho&ic UPDATE Ban biến đổi các câu lệnh INSERT hoặc UPDA'TTE thành
các lệnh gọi hàm bằng cách thêm mệnh đề này
Mệnh đề RETURNING khai báo một tham số chế độ OUT hình thức
đưới dang đích của vị ngtt INTO Ménh dé neo (anchor) mét bộ mô tả
(descriptor) cột sang biến chế độ OUT Tham số thật sự phải là một biến
CLOB hoặc NCLOB được khai báo Thực tế nó mở nguồn tài nguyên luéng (stream resource) vào cột đối tượng lớn nhằm cho bạn tránh những giới hạn kích cỡ của SQL và PL/SQL Hình 8.1 minh họa tiến trình về
cách làm việc của ménh dé RETURNING INTO
Bạn có khả năng ghi sang cột CLOB hoặc NCLOB từ đầu một lệnh
INSERT hoặc UPDATE (vốn mở nguồn) cho đến cuối phạm vi giao tác Một câu lệnh COMMIT hoặc ROLLBACK kết thúc phạm vi giao tác bên trong khối SQL hoặc PL/SQL va déng luéng đối tượng lớn Một sắc thái khác là sự kết thúc của khối độc lập vốn cũng có thể commit việc ghi
Mệnh để RETURNING nhận dạng
tham số hình thức bằng cách neo nó sang một tên cột Nó cũng xác lập chế
độ hoạt động sang chế độ IN và OUT
(hoặc chuyển theo tham chiếu)
Bộ định vj goi (Call Locator) Cơ sở
Bộ định vị khứ hồi (Return Locator) dữ liệu
Mệnh đề INTO gán một biến cục
bộ dưới dạng tham số thật sự của
1 một lệnh gọi hàm để tạo một nối kết cơ sở dữ liệu Nối kết cho bạn ghi dữ liệu sang một locator BLOB
hoặc CLOB trong một giao tác
Đầu ra tham
chiếu
Hình 8.1 Cấu trúc hàm định vị L0B ngẩm định
Trang 10Chương 8: Các đối tượng lớn 13
Nguyên mẫu câu lệnh INSERT và UPDATE sau đây minh họa một
phương pháp đặc biệt để quản lý các kiểu dữ liệu LOB Từ khóa RE-
TURNING của mệnh đề RETURNING INTO lúc đầu vụng về nhưng nó
có nghĩa là phân kênh tham chiếu cột vào một biến cục bộ
Câu lệnh INSERT
Câu lệnh INSERT khởi tạo một cột CLOB va sau đó nó trả về locator
qua câu lệnh RETURNING INTO vào một biến cục bộ Biến cục bộ được
chuyển theo tham chiếu và có chế độ hoạt động OUT Bạn có thể xem
chương 6 để biết chỉ tiết về hoạt động chế độ OUT, nhưng đặc biệt nó
không cho phép gởi một giá trị đến một tham số hình thức trong một
chữ ký hàm Trong câu lệnh INSERT, việc gán bên trong mệnh đề các
giá trị có vai trò như là một phân của hoạt động chế độ IN Việc chèn
cũng bắt đầu một phạm vi giao tác Bạn có thể thêm vào hoặc thay thế
nội dung được trỏ vào locator trong phạm vi của giao tác này
Câu lệnh UPDATTE xác lập giá trị cột CLOB bang ham EMPTY_CLOB
va sau a6 né tra vé column locator (bộ định vị cột) qua mệnh đề RE-
TURNING INTO vao mét biến cục bộ Biến cục bộ được chuyển theo
tham chiếu và có một chế độ hoạt động OÚT Như câu lệnh [NSERT, sự
cập nhật cũng bắt đầu phạm vi giao tác Bạn có thể thêm vào hoặc thay
thế nội dung được trỏ vào bởi locator trong phạm vi của giao tác
Trang 1114 Chương 8: Các đối tượng lớn
Xác lập giá trị
UPDATE table_ name cột ban đầu
SET column_namet = columr, valuel
Cuối cùng, đọc và ghi trong các cụm cần thiết cho các file có kích cỡ
hàng trăm megabytes, gigabytes, hoặc terabytes nhưng không phải cho
các fñle nhỏ hơn 100 megabytes Một số nhà phát triển chuyển sang C,
C++, C#, Java hoặc PHP để hoàn tất việc đọc và ghi các ñle CLOB nhỏ PL/SQL hỗ trợ việc ghi những file này mà không phụ thuộc vào các file bên ngoài Mục nhỏ đầu tiên hướng dẫn bạn đọc các fñle ngoài và ghỉ
chúng dưới dạng các cột CLOB Giải pháp trong mục này sử dụng riêng
PL/SQL Mục nhỏ tiếp theo trình bày một ví dụ PHP hướng dẫn cách
upload một file, ghi trực tiếp luồng đữ liệu sang một cột CLOB và sau đó
đọc nội dung cột vào một trang web :
Các phần phụ sau đây thảo luận những phương pháp đọc và ghi các
cột CLOB hoặc NCLOB sang các cột cơ sở dữ liệu Mục thứ nhất thảo
luận một giải pháp server cơ sở dữ liệu và mục thứ hai cung cấp bạn một
thủ tục PL/SQL để hỗ trợ việc upload CLOB hoặc NCLOB từ xa
PL/SQL dge cdc File va ghi các cịt ÊLũB hoặc NCLOB
Gói DBMS_LOB cung cấp tất cả công cụ cần thiết để tải trực tiếp các đối tượng lớn khi chúng vượt quá những giới hạn luồng byte của SQL
hoặc PL/SQL Bước đâu tiên đòi hỏi bạn định nghĩa một thư mục ảo
(virtual đirector) Điều này được thực hiện cho bạn khi bạn chạy script create_user.sqÌ từ web site của nhà xuất bản Thư mục ảo là một bí đanh
thư mục nội tại trổ vào một đường dẫn
Trong ví dụ này, ban tạo một thư mục ảo trổ vào thư mục cục bộ tạm
thời của bạn Bạn phải kết nối dưới dạng người dùng SYSTEM để định
nghĩa các thư mục ảo Các lệnh sau đây làm việc trên hệ điều hành cụ
thể của bạn: :
Linux hoge Unix
CREATE DIRECTORY generic AS ‘/tmp’;
Trang 12Chương 8: Các đối tượng lớn 15
Windows
CREATE DIRECTORY generic AS ‘C:\Windows\temp’;
Đau khi bạn thư mục ảo, bạn cần cấp phát các quyền đọc trên thư mục
cho người dùng plsql Cú pháp là
GRANT READ ON DIREGTORY generic TO plsql;
Các bước tiếp theo là đọc fñile và ghi dữ liệu sang cột CLOB Trong khi
vài đoạn mã nhỏ có thể trình bày những khái niệm, một ví dụ mã hoạt động được cho Bằng cách này, bạn có thể cắt và đán nó ngay vào các
ứng dụng của bạn Ví dụ sử dụng NDS (Native Dynamic SQL) Bạn nên
tham khảo chương 11 nếu bạn tò mò về những cơ cấu cha NDS
Thủ tục load_clob_ftrom_ñle sau đây minh họa cách làm điều này:
“= Thỉs is found in load_clob_from_file.sql on the publisher's weh site CREATE OR REPLACE PROCEDURE load_clob_from_file
Opening source file is a mandatory operation
IF dbms_lob.fileexists(src_clob) = 1 AND NOT dbms_lob.isopen (src_clob) = 1 THEN
src_clob_size := dbms_lob.getlength(src_clob);
dbms_lob.open(src_ciob, DBMS_LOB.LOB_READONLY);
Trang 1316 Chương 8: Các đối tượng lớn
END IF;
Assign dynamic string to statement
stmt := ‘UPDATE ‘| | table_name 11‘ ' [| ‘SET 'l | column_name |! ' = empty_clob() '
HT ‘WHERE ‘1 | primary_key_name [1° ='I1 ‘|| primary_key_valuel |" * [1 ‘RETURNING ‘I | column_name | | ' INTO :locator';
Run dynamic statement
EXECUTE IMMEDIATE stmt USING OUT des_clob;
Read and write file to CLOB, close source file and commit
dbms_lob.loadclobfromfile( dest_lob => des_clob
, Sf0_bfile => src_clob
, amount => dbms_lob.getlength(src_clob)
, dest_offset => des_offset , 81C_Offset => src_offset , bfile_csid => dbms_lob.default_csid
ELSE SIF $$DEBUG = 1 $THEN dbms_output.put_line('Failure ');
$END RAISE dbms_lob.operation_failed;
END IF;
END load_clob_from _file;
/
Thủ tục đòi hỏi các đối số để sử dụng nó trên bất kỳ table nào có một
cột CLOB và một khóa chính của cột Lệnh gọi thủ tục DBMS_LOB.OPEN
mở ñle ngoài và đọc nó vào một kiểu dữ liệu BFLIR Hàm BFILENAME
bảo vệ đường dẫn thư mục chuẩn tắc từ catalog cơ sở dữ liệu và thêm tên file Hàm BEILENAME trấ về một tên file chuẩn tắc, Câu lệnh UP-
Trang 14Chương 8: Các đối tượng lớn 17
DATE dong xác lập cột CLOB sang mét empty_clob() Sau đó, câu lệnh
UPDATE tra vé cột được ấn định vào một biến đầu ra Biến liên kết
:locator là biến đầu ra trong câu lệnh NDS Bạn gán locator CLOB sang
biến des_clob khi câu lệnh NDS chạy
Câu lệnh UPDATE sử dụng RETURNING INTO sé thay đổi giá trị
cột đích cho tất cả hàng cập nhật
Tất cả hành động trước đọc file nguồn và liên kết với một bộ định vi cột CLOB vào phạm vi chương trình Với hai phương thức xử lý nguồn tài nguyên này, lệnh gọi dén thi tue LOADCLOBFROMFILE chuyén nội dung của file mở sang bộ định vị CLOB Hoạt động đọc và ghi này không bi gidi han xt ly 32.767 byte cua PL/SQL N6 cing là một phương pháp 4 để đọc trực tiếp các cụm file lớn vào các cột CLOB Các giá trị dịch chuyển file nguồn (src_offset) và các giá trị địch chuyển cột CLOB đích (dest_offset) cho ban phan tích cú pháp | cdc cum ti file va dat ching trong c6t CLOB Tất ca những gì bạn cần làm là thêm logic cho một vòng lặp, vì các ñle mẫu tương đối nhỏ nhưng lớn hơn 4.000 bytes (vốn giới hạn một phép gán trực tiếp bên trong một câu lénh UPDATE)
Bạn có thể test thủ tục lưu trữ này bằng cách chạy chương trình khối
nặc danh sau đây:
This is found in load_clob_from_file.sql on the publisher's web site
BEGIN
FOR i IN (SELECT item_id
FROM item WHERE item_title = 'The Lord of the Rings - Fellowship of the Ring’
AND item_type IN
(SELECT common_lookup_id FROM common_lookup WHERE common_lookup_†able = 'ITEM' AND common_lookup_column = 'ITEM_TYPE' AND REGEXP_LIKE(common_lookup_type,'*(dvdivhs)*’,'i'})) LOOP
Call reading and writing CLOB procedure
load_clob_from_tile( src_file_name => 'L0TRFellowship.txt'
, tahle_name => 'TTEM' , column_name => ‘ITEM_DESC' , primary_key_name => ‘ITEM_ID' , primary_key_value => TO_CHAR(i.item_id)); END LOOP;
Trang 1518 Chương 8: Các đối tượng lớn
END;
/
Lệnh gọi đến thủ tục load_clob_from_file được thực hiện cho mọi giá trị item_¡đ đáp ứng quy tắc nghiệp vụ được xác định bởi phép tìm kiếm
biểu thức thông thường Biểu thức thông thường nhận được tất cả hàng
DVD và VHS nơi item _ title là “The Lord of the Rings - Fellowship of the
Ring” và item_type ánh xạ sang một giá trị chuẩn bắt đâu với một chuỗi
con DVD hoặc VHS
Ban có thé chay dinh dang va query sau đây để xác nhận rằng ba hàng bây giờ có các cột CLOB với các luồng dữ liệu đài hơn 4.000 bytes
Format column for output
COL item_id FORMAT 9999
COL item_title FORMAT A50
COL size FORMAT 9,999,990
Query column size
It yields the following three rows:
ITEM_ID ITEM_TITLE SIZE
1037 The Lord of the Rings - Fellowship of the Ring 5,072
1038 The Lord of the Rings - Fellowship of the Ring 5,072
1039 The Lord of the Rings - Fellowship of the Ring 5,072
Upload cac CLOB lén cu si di liệu
Nhu PL/SQL, các ngôn ngữ lập trình bên ngoài làm việc với những
giới hạn giống y như để upload và ghi các cột CLOB hoặc NCLOB Bạn
phải chọn nhập các cụm nhỏ 32.767 bytes) hay các cụm lớn 1MB trở lên Mục này giả định bạn muốn upload và ghỉ các cụm lớn thông qua các
chương trình bên ngoài ;
Giải pháp sau đây tạo một thủ tục PL/SQL có khả năng hỗ trợ bất kỳ
ngôn ngữ lập trình web bên ngoài làm việc với các thư viện Oracle JDBC
hoặc OCI8 Nó cho phép xác lập lại và thêm một giá trị cột CLOB hoàn
chỉnh, nhưng bạn nên nhớ các file quá lớn sẽ được ghi dưới dạng các cựm
:
Trang 16Chương 8: Các đối tượng lớn 19
This is found in create_web_clob_loading.sql on the publisher's web site CREATE OR REPLACE PROCEDURE web_load_clob_from_file
SET item_desc = empty_clob()
WHERE item_id = item_id_in
RETURNING item_desc INTO descriptor;
END web_load_clob_from_file;
/
Thủ tục này cho bạn mở một bộ định vị CLOB và truy cập nó từ ñle chương trình từ xa Có ba tính năng chính trong thủ tục này Thứ nhất, tham số hình thức là một bộ định vị CLOB với một sự truy cập chế độ IN
OUT Thứ hai, mệnh đề RETURNING TNTO cung cấp một cổng nối biến
cục bộ vào biến mệnh đề SET Thứ ba, việc thiếu một COMMTT trong
thủ tục lưu trữ làm cho lớp bị khóa và phạm vi giao tác DML mở cho chương trình web bên ngoài
Những mục trên đã trình bày cách đọc và ghi các cột CLOB và NCLOB
trên tầng cơ sở dữ liệu và thông qua các chương trình bên ngoài
Các đối tượng lớn nhị phân: Kiểu dữ liệu BL0B
Kiểu dữ liệu BLOB có thể định nghĩa một cột trong một table hoặc
nested table Như kiểu đữ Hệu CLOB, nó có kích cỡ vật lý tối đa giữa 8 và
128 tegabytes Kiểu dữ liệu BLOB cho phép lưu trữ các ñle nhị phân lớn
như các ảnh, track nhạc, phim (movie) hoặc các file Portable Document Format (PDF) Mục này xem xét cách bạn có thể upload, ghi và đọc các kiểu đữ liệu BLOB
Chi che
Nhu kigu da lieu CLOB, kigu da lige BLOD có kích cỡ cội lối đa được xác lập
bãi tham số khải tgo co sé dữ liệu db_block_size Kich ca khei SKB mặc định
Các cột BLOB thường được lưu trữ riêng biệt với phần còn lại của hàng trong một table Chỉ descriptor hoặc locator được lưu trữ vật lý
trong cột Locator trổ vào nơi nội dung vật lý của một BLOB được lưu trữ
và cung cấp một tham chiếu dẫn sang vùng làm việc riêng trong SGA
Vùng làm việc này cho phép đọc và ghỉ các cụm dữ liệu mới Một số gọi
Trang 1720 Chương 8: Các đối tượng lớn handle BLOB là descriptor (bộ mô tả) và giữ lại biệt hiệu locator cho thời điểm chúng làm việc với các BEFILE ngoài Một trong hai làm việc, nhưng tài liệu Oracle 11g bắt đầu gọi cả hai là các locator một cách nhất quán Sách này tuân theo quy ước đó và gọi chúng là các locator
Như kiểu đữ liệu CLOB, kiểu đữ liệu BLOB là một loại đối tượng Nó đòi hỏi việc xây dựng ngầm định hoặc tường minh Bạn có thể xây dựng biến BLOB một cách ngâm định bằng cách gán một giá trị rỗng, một phương thức tạo empty_blobQ hoặc một chuỗi thập lục phân Chương 3
dé cập việc khởi tạo và gán các giá trị vào các kiểu dit ligu BLOB Các ví dụ sau đây xem lại cách ban khai báo một biến BLOC:
var1 BLOB; Declare a null reference to a BLOB
var1 BLOB := empty_blob(); Declare an empty BLOB
var2 BLOB := ‘43'1 | '41'l | '52'; Declare a hexadecimal BLOB for CAR
Có hai cách để tập hợp lại các cột BLOB Bạn có thể tải một ñle phía server bằng cách gọi các thủ tục OPEN, LOADBLOBFROMFILE va CLOSE duoc tim thay trong gói DBMS_LOB Bạn có thể sử dụng một ngôn ngữ lập trình bên ngoài như Java hoặc PHP Java sử dụng các thu viện JDBC để ghi mét luéng nhị phân (binary stream) sang một cột BLOB, và PHP sử dụng các thư viện OCI8 để ghi một luồng nhị phân Các cột BLOB khác với các kiểu dữ liệu vô hướng vì cùng một lý do
rằng các cột CLOB khác nhau Chúng cũng không bị giới hạn chỉ trong các trạng thái NULL hoặc NOT NULL C4c BLOB, CLOB va NCLOB 14 NULL, empty, hodc populated như được trình bày trước đó trong bảng 8.1
Như trong trường hợp của các cột CLOB, có một vấn đề với phương pháp này Nó không tận dụng mệnh đề RETURNING INTO mà bạn có
thể thêm vào bất kỳ câu lệnh DML INSERT hoặc UPDATE Bạn biến đổi các câu lệnh INSERT hoặc [PDATE thành các lệnh gọi hàm bằng
cách bổ sung mệnh dé nay
Mệnh để RETURNING khai báo một tham số chế độ OUT hình thức dưới dang đích của vị ngữ INTO Mệnh đề neo (anchor) một bộ mô tả cột (column descriptor) sang biến chế độ OUT Tham số thật sự phải là một biến BLOB được khai báo Thực tế nó mở một nguồn tài nguyên luồng
vào cột đối tượng lớn giúp tránh những giới hạn kích cỡ của SQL và PL/ SQL Hinh 8.1 trước đó trong chương này minh hoa tién trinh vé cdch
lam viéc cua ménh dé RETURNING INTO
Ban cé thé ghi sang cột BLOB từ đầu một câu lệnh INSERT hoặc
UPDATE (vốn mở luồng) cho đến cuối phạm vi giao tác Một câu lệnh
COMMTT hoặc ROLLBACK kết thúc phạm vi giao tác bên trong một khối SQL hoặc PL/SQL và đóng luông đối tượng lớn Một sắc thái khác
là sự kết thúc của một khối độc lập mà cũng phải commit việc ghi
Trang 18Chương 8: Các đối tượng lớn 21
Các nguyên mẫu câu lệnh INSERT và UPDATE sau đây minh họa
một phương pháp đặc biệt để quản lý các kiểu dữ liệu LOB Chúng là các
ảnh gương với những ảnh làm việc với các kiểu đữ liệu CLOB và NCLOB
nhưng đối với phương thức tạo empty_blobQ Từ khóa RETURNING của
mệnh dé RETURNING INTO nghĩa là phân kênh tham chiếu cột vào
một biến cục bộ
Câu lệnh INSERT
Câu lệnh INSERT khởi tạo một cột BLOB, và sau đó nó trả về locator
thông qua mệnh đề RETURNING INTO vào một biến cục bộ Biến cục
bộ được chuyển theo tham chiếu và nó có chế độ hoạt động OUT Bạn có
thé xem chương 6 để biết chỉ tiết về hoạt động chế độ OUT, nhưng đặc
biệt nó không cho phép gởi một giá trị đến một tham số hình thức trong
một chữ ký hàm Trong câu lệnh INSERT, việc gán bên trong mệnh đề
các giá trị có chức năng như là một phần của hoạt động chế độ IN Việc
chèn (insert) cũng bắt đầu một phạm vi giao tác Bạn có thể thêm vào
hoặc thay thế nội dung được trỏ vào bởi locator trong phạm vi của giao
Câu lệnh UPDATE giả định column_name2 là một kiểu đữ liệu BLOB
Nó xác lập giá trị của cột BLOB và sau đó nó trả về locator thông qua
mệnh đề RETURNING INTO đến một biến cục bộ Biến cục bộ được
chuyển theo tham chiếu và nó có một chế độ hoạt động OUT Nhu cau
lệnh INSERT, câu lénh UPDATE bắt đầu một phạm vi giao tác Bạn có
thể thêm vào hoặc thay thế nội dung được trỏ vào bởi locator trong
phạm vi của giao tác này
Í
Trang 1922 Chương 8: Các đối tượng lớn
liệu của cột được Xác lập tên
tham chiếu biến cục bộ
Hai mục tiếp theo minh họa cách đọc các file lớn hơn giới hạn PL/
SQL cho dữ liệu ký tự và ghi chúng sang các cột BLOB Mục thứ nhất
minh họa cách ghi module PL/SQL dé tai một BLOB Thật không may,
bạn không thể đọc từ một BLOB từ cơ sở đữ liệu vào SQL*Plus đưới đạng
bất cứ thứ gì ngoại trừ chuỗi nhị phân Các ví dụ đọc và hiển thị sử dụng PHP dé minh hoa cách nó được upload, được ghi sang cơ sở đữ liệu và được kết xuất trong một trang web như thế nào
PL/SQL dc cae File va ghi các cột BLOB
Gói DBMS_LOB cung cấp tất cả công cụ cần thiết để tải trực tiếp các
đối tượng lớn khi chúng vượt quá những giới hạn bộ đệm (buffer) của SQL hoặc PL/SQL Bước đầu tiên đòi hồi bạn định nghĩa một thư mục ảo (virtual directory) Tuy nhiên, như được để cập trong mục “PL/SQL đọc
các File và ghi các cột CLOB hoặc NCLOB”, thư mục cơ sở đữ liệu ảo này
phải trỏ vào một đường dẫn chuẩn tắc Như trong ví dụ CLOB, bạn cần
tạo một thư mục ảo ánh xạ sang thư mục hệ điều hành tạm thời
Bạn phải kết nối dưới dạng người dùng SYSTEM để định nghĩa các
thư mục ảo Nếu bạn đã tạo thư mục ảo này trong phân vừa rồi, bạn có
thể bỏ qua việc tái định nghĩa chúng ở đây Các lệnh sau đây làm việc
phụ thuộc vào hệ điều hành cụ thể:
Linux hode Unix
CREATE DIRECTORY generic AS ‘/tmp':
Windows
CREATE DIRECTOR generic AS ‘C:\Windows\temp’:
Trang 20Chương 8: Các đối tượng lớn 23
Sau khi tạo thư mục ảo, bạn cân cấp phát các quyền đọc trên thư mục
cho người dùng plsgl Cú pháp là
GRANT READ 0N DIREGTORY generic TO plsql,
Bước kế tiếp là đọc file và ghi đữ liệu sang cột BLOB Trong khi một
vài đoạn mã nhỏ có thể trình bày các khái niệm, một ví dụ mã hoạt động được cho Ví dụ này sử dụng NDS (Native Dynamic SQL), tham khảo nội
dung được đề cập trong chương 11
Thủ tục load_blob_from_file sau đây minh họa cách làm điều này:
-« This is found in load_blob_from_file.sql on the publisher's web site
CREATE OR REPLACE PROCEDURE load_blob_from_tile
Opening source file is a mandatory operation
IF dbms_lob.fileexists(src_blob) = 1 AND NOT dbms_lob.isopen(src_blob)
= 1 THEN src_blob_size := dbms_lob.getlength(src_blob);
dbms_lob.open(src_blob, DBMS_LOB.LOB_READONLY);
END IF;
Assign dynamic string to statement
stmt = ‘UPDATE ‘I | table_name | 1" *
11 ‘SET ‘I | column_name | | ‘ = empty_blob() ˆ I1 ‘WHERE ‘1 | primary_key_name fi’ = ‘11° EI primary_key_valuel | "" '
¡1 'RETURNING '1 I column_name I I ' INTO :locator';
Trang 2124 Chương 8: Các đối tượng lớn
Run dynamic statement
EXECUTE IMMEDIATE stmt USING OUT des_biob;
Read and write file to BLOB
dbms_iob.loadblobfromfile( dest_lob => des_blob
, Sr€_bfile => src_blob , amount => dbms_ lob.getlength(src_blob) , dest_offset => des_offset
, Src_offset => src_offset );
-~ Close open source file
dbms_lob.close(src_blob);
Commit write
IF src_blob_size = dbms_tcb.getlength(des_blob) THEN
$iF $$DEBUG = 1 $THEN dbms_output.put_line(‘Success!');
SEND COMMIT, ELSE
SIF $$DEBUG = 1 $THEN dbms_output.put_line('Failure.*);
hữu và không mở, lệnh gọi thủ tục DBMS_LOB.OPEN mở file ngoài và
đọc nó vào một kiểu đữ liệu BFILE Hàm BEILENAME bảo vệ đường
dẫn thư mục chuẩn tắc từ catalog cơ sở dữ liệu và thêm tên file Hàm BEILENAME trả về một tên file chuẩn tắc Câu lệnh UPDATE động xác
lập cột BLOB sang một empty_blob() và sau đó trả cột vào một biến đầu
ra Biến liên kết :locator là biến đầu ra trong câu lệnh NDS Chương
trình trả về một bộ định vị BLOB và gán nó sang biến des_blob khi câu
lệnh NDS chạy Kích cỡ file ngoài được so sánh với cột BLOB được
upload trước khi commit giao tác Các khóa mã có điều kiện báo hiệu việc hoàn tất thủ tục thành công hoặc không thành công khi bạn đã xác
lập tùy chọn PLSQL_CCFLAGS trong session như được trình bày trong chương 4.
Trang 22Chương 8: Các đối tượng lớn 25 Tất cả hành động trước đọc file nguồn và bộ định vị cột BLOB đích vào phạm vi chương trình Với hai bọ xử lý nguồn tài nguyên này, lệnh
gọi đến thủ tục LOADBLOBEFROMFILE chuyển nội dung của file mở
sang bộ định vị BLOB Hoạt động đọc và ghi này cho phép đặt trực tiếp
các cụm file lớn vào các cột BLOB Giá trị dịch chuyển fñle nguồn
(sre_offset) và giá trị dịch chuyển cột BLOB đích (dest_offset) cho ban phân tích cú pháp các cụm từ ñle và đặt chúng trong cột BLOB Bạn có
thể thêm một vòng lặp để tiếp cận việc upload mỗi lần một cụm cho các
file nhị phân rất lớn như các phim (movie)
Bạn có thể test thủ tục lưu trữ này bằng cách chạy chương trình khối
nặc danh sau đây:
This is found in toad_blob_ƒrom_file.sql on the publisher's web site BEGIN
FOR i IN (SELECT item_id
FROM item WHERE item_title = ‘Harry Potter and the Sorcerer’’s Stone’ AND item_type IN
(SELECT common_lookup_id
FROM common_lookup WHERE common_lookup_table = 'ITEM’
AND common_lookup_column = ‘ITEM_TYPE' AND REGEXP_LIKE(common_lookup_type,'*(dvdlvhs)*','i'))) LOOP Call procedure for matching rows
load_blob_from_file( src_file_name => 'HarryPotter1.png'
, table_name => 'ITEM' , column_name => 'ITEM_BLOB' , primary_key_name => 'ITEM_]D' , primary_key_value => TO_CHAR(i.item_id) ); END LOOP;
Trang 2326 Chương 8: Các đối tượng lớn
một giá trị chuỗi bắt đầu với một chuỗi con DVD hoặc VHS, nghĩa là các ảnh được tải vào tất cả cột đích cho bất kỳ hàng tương ứng
Bạn có thể chạy phần định dạng và query sau đây để xác nhận hai hàng bây giờ có các cội BILOB với các luỗng dữ liệu nhị phân dài hơn
Format column for output
COL item_id FORMAT 9999 COL item_title FORMAT A50 COL size FORMAT 9,999,990
Query column size
SELECT item_id , item _title
; dbms_lob.getlength(item_blob) AS “SIZE”
FROM item ‘ WHERE dbms_lob.getlength(item_blob) > 0;
N6 tao ra ba hang sau day:
ITEM_ID ITEM_TITLE SIZE
1021 Harry Potter and the Sorcerer's Stone 121,624
1022 Harry Potter and the Sorcerer's Stone 121,624
Như được thảo luận trong phần song song cho các cột CLOB, các ngôn ngữ lập trình ngoài làm việc với những giới hạn y như thế để upload và ghi cdc edt BLOB Bạn phải chọn ngôn ngữ và phương pháp nào làm việc
tốt nhất cho tổ chức của bạn Mục này giả định bạn muốn upload toàn bộ
ảnh dưới dạng một file nhị phân (binary)
Giải pháp sau đây tạo một thủ tục PL/SQL hỗ trợ bất kỳ ngôn ngữ lập
trình web ngoài nào làm việc với các thư mục Oraele JDBC hoặc OCI8
Nó cho phép bạn xác lập lại và thêm một giá trị cột BLOB hoàn chỉnh, nhưng bạn nên nhớ rằng các file lớn quá sẽ được ghi đưới dạng các cụm
This is found in create_web_blob_loading.sql on the publisher's web site
CREATE OR REPLACE PROCEDURE web_load_blob_from_fite
( item_id_in IN NUMBER
, descriptor IN OUT BLOB ) Is
BEGIN
>
Trang 24Chương 8: Các đối tượng lớn 27
A FOR UPDATE makes this a DML transaction
UPDATE item
SET item_biob = empty_blob()
WHERE item_id = item_id_in
RETURNING item_blob INTO descriptor;
END web_load_blob_from_file;
/
Thủ tục này cho bạn mở một bộ định vị BLOB và truy cập nó từ một
file thư viện PHP Có ba tính năng chính trong thủ tục này Thứ nhất,
tham số hình thức là một bộ định vị BLOB với một sự truy cập chế độ IN
OUT Thứ hai, mệnh đề RETƯRNING TNTO cung cấp một cổng nối biến cục bộ vào biến mệnh đê SET Thứ ba, việc thiếu một COMMTT làm cho
BLOB bị khóa và phạm vi giao tác DML mở cho các chương trình web ngoài
Những mục trên đã trình bày cách đọc và ghi các cột BLOB trên tầng
cơ sở đữ liệu và thông qua các chương trình bên ngoài
Securefiles
SecureFiles là các đối tượng lớn đặc biệt Chúng được khai báo bằng những tham số lưu trữ đặc biệt vốn cho bạn mã hóa, nén và và hủy sao
chép chúng
Oracle 11g cho phép lưu trữ SecureFiles trong các cột BLOB, CLOB
va NCLOB SecureFiles cho phép mã hóa, nén và hủy sao chép cdc LOB
Chúng làm việc theo nguyên tắc Transparent Data Encryption (TDE) và
sử dụng một Oracle Wallet làm khóa mã hóa
TDE cho bạn chọn một thuật toán mã hóa không mặc định Bạn có
thể chọn từ những thuật toán mã hóa sau đây:
M 3DES168
M AES128
AES192 (default)
E AES256
Bạn có thể kiểm tra xem instance có được cấu hình để làm việc với
SecureEFiles hay không bằng cách truy vấn khung xem (view) vồparameter Query và định dạng SQL*Plus là
COLUMN name FORMAT Ai4
Trang 2528 Chương 8: Các đối tượng lớn
COLUMN value FORMAT A14
SELECT name, value FROM v$parameter WHERE name LIKE 'db_securefile’;
Ít ra bạn nên có các đòng sau đây để làm việc với SecureFiles:
db securefile PERMITTED|
Bước tiếp theo đòi hỏi bạn thiết lập mét password ma héa trong một
Wallet Oracle 11g Cách dễ nhất để cấu hình Wallet là chạy Oracle 11g
Wallet Manager
Các lệnh được ghi chú ở đây:
Linux hoặc Dnix
# $ORACLE_HOME/bin/owm
Windows
C:> %ORACLE_HOME%\bin\launch.exe “oracle_canonical_path\bin” owm.cl
Lệnh menu có lẽ dễ hơn Nó là: Start | Programs | Oracle - Oracle Home | Integrated Management Tools | Wallet Manager Bén trong Wallet Manager, bạn có thể tạo một khóa mã hóa Bạn nên lưu nó sang
sé tim thay trong thư mục /network/admin (các dấu gạch chéo ngược cho
Windows) của Oracle Home Tên file wallet là ewallet.p12
Bạn nhập các dòng sau day trong file sq]net.ora:
Trang 26Chương 8: Các đối tượng lớn 29
Sau khi đọc password Wallet, bạn tạo một tablespace đặc biệt cho 8ecureFiles như
CREATE TABLESPAGE securefiles
DATAFILE '<canonical_path>\sec_file.dbf SIZE 5M
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;
Giữ hài hòa với ví dụ cửa hàng video, bạn sẽ thêm một cột CLOB secure file vào table item Cú pháp sau đây cho phép tạo cột mới dưới dang mét secure file:
ALTER TABLE item ADD (sec_file CLOB) LOB(sec_file)
STORE AS SECUREFILE sec_file (TABLESPACE securefile);
Bây giờ bạn có thể thay đổi và mã hóa cột:
ALTER TABLE item MODIFY L0B(sec_file) (ENGRYPT USING '3DES168);
Bây giờ bạn có một cột được mã hóa trong table item Bất kỳ LOB
được lưu trữ bên trong hỗ trợ SecureFiles, nhưng bạn nên đặt chúng trong tablespace riêng của chúng
Các file Binary: Kiểu đữ liệu BFILE
Kiểu đữ liệu BEILE (binary ñle) làm việc khác với các kiểu đữ liệu BLOB, CLOB, và NCLOB tương ứng Các điểm khác biệt lớn nhất là các
giá trị BEILE là những kiểu đữ liệu LOB read-only (chỉ đọc) và được lưu
trữ bên ngoài cơ sở dữ liệu Không giống như các kiểu dữ liệu BLOB, CLOB và NCLOB, BFILE có một kích cỡ vật lý tối đa được xác lập bởi hệ
điều hành
Các BFILE ngoài tượng trưng cho dữ liệu không phù hợp trong các
kiểu đữ liệu chuẩn, chẳng hạn như các ảnh (image), các file PDF, tài liệu
Microsoft Office và movie QuickTime Những ñle ngoài này liên quan
đến các thành phần nghiệp vụ bên trong cơ sở dữ liệu bằng cách lưu trữ
một bộ mô tả file ngoài trong một cột BEILE Nói chung, chúng được phục vụ cho các khách hàng Internet hoặc intranet thông qua các trình duyệt web Các trình duyệt web sử dụng loại nội dung MIME để hiểu chúng sẽ kết xuất những tài liệu này như thế nào, điều này thường đòi
hồi các plug-in trình duyệt để quản lý sự truy cập và hiển thị
Mục nhỏ đầu tiên khai thác cách bạn cấu hình và sử dụng cơ sở dữ
liệu để tận dụng các file ngoài được tham chiếu dưới dạng các cột BEFILE
Bạn sẽ thiết lập một thư mục ảo khác (như các thư mục trong các phan
trước), định nghĩa một bộ định vị BFILE và kiểm tra cách các thư mục
ảo giới hạn sự truy cập đến những tên ñle chuẩn tắc của các file nguồn
Trang 27
BEILE ngoài như thế nào Đồng bộ hóa các thư mục ảo Apache và Oracle
là một chiến lược triển khai truyền thống khi sử dụng các fñle nguồn BEILE ngoài
Mục nhỏ thứ hai hướng dẫn cách mở rộng catalog cơ sở đữ liệu và đọc
các tên file chuẩn tắc nhằm đơn giản hóa cách bạn gọi các ñle ngoài từ những chương trình phía server Điều này hữu dụng khi bạn muốn lưu
trữ các ñle bên trong trong cơ sở đữ liệu
Tao và sil dung tác thứ mục ả0
Các thư mục ảo (virtual directories) giống như các từ đồng nghĩa (synonyms); chúng trỏ vào một thứ khác - một thư mục vật lý trên hệ
điều hành Các tên thư mục ảo và vật lý được lưu trữ trong catalog cơ sở
dữ liệu và có thể xem trong khung xem đba_directories Những người
dùng cơ sở đỡ liệu có thể xem chúng khi họ được cấp phát đặc quyển
SELECT trén khung xem hoac vai trod SELECT_CATALOG_ROLE Theo mac dinh, nguéi dung SYSTEM truy c4p khung xem dba_directories thông qua vai trò SELECT_CATALOG_ROLE
Bạn thường tạo các thư mục ảo dưới dạng người dùng SYSTEM hoặc
một người dùng cơ sở dữ liệu khác tận hưởng đặc quyền vai trò DBA
Hoặc, người dùng SYSTEM có thể cấp phát đặc quyền CREATE ANY
DIRECTORY cho một người dùng Điều này giảm bớt gánh nặng từ DBA
nhưng có thể dẫn đến việc sinh sôi nầy nở của các thư mục ảo và những
xung đột tiềm ẩn trong việc đặt tên Nói chung bạn không nên cho phép những người dùng ngoại trừ DBA tạo các thư mục
Tất cả các thư mục ảo thật ra do người dùng SYS sở hữu Thư mục vật
lý luôn là đường dẫn chuẩn tắc, nghĩa là một đường dẫn thư mục được xác định đây đủ Một đường dẫn chuẩn tắc Linux hoặc Unix bắt đầu tại
một điểm cài đặt (mount) và kết thúc tại thư mục mong muốn Một
đường dẫn file chuẩn tắc Windows bắt đầu tại mẫu tự ổ đĩa vật lý và như trong Linux hoặc nix kết thúc tại thư mục mong muốn
Bạn nên kết nối đưới dạng người dùng SYSTEM và định nghĩa một
thư mục ảnh ảo Các lệnh sau đây làm việc trên hệ điều hành riêng biệt
của bạn:
Linux hodec Unix
CREATE DIRECTORY images As '/NaTNWW/html/images';
Windows
CREATE DIRECTORY images AS 'GAProgram Files\Apache Group\Apache2whtdocs\images"; P
Trang 28Chương 8: Các đối tượng lớn 31
Sau khi tạo thư mục ảo, dưới dạng người dùng SYSTEM bạn cần cấp
phát các quyền đọc trên thư mục cho người dùng plsgl Cú pháp là
GRANT READ ON DIRECTORY imagss TO plsql;
Các bước kế tiếp thường bao gồm tao một } bí danh (alias) va thu mục
ảo trong file Apache httpd.conf Nếu bạn muốn cấu hình bí danh và thư
mục ảo Apache, bạn có thể xem phần “Tạo một bí danh và thư mục ảo
Apache” Có những lý do rất tốt để xác lập các bí danh và thư mục ảo
trong Apache Theo quy tắc, bạn phải mirror định nghĩa trong bí danh
và thư mục ảo Apache với cấu hình của thư mục ảo cơ sở dữ liệu Oracle
Có quy tắc bởi vì thủ tục FILENAME của gói DBMS_ LOB cung cap chi
tên file cơ sở; nó không cung cấp một phương tiện để tìm các tên file
chuẩn tắc Các tên file chuẩn tắc là sự kết hợp của các đường dẫn chuẩn
tắc và các tên file cơ sở đữ liệu
Tạo một hí danh và thư mục ảo Apache
Hai bước cấu hình Apache là bắt buộc khi bạn muốn bật một thư mục ảo
mới Bạn cần cấu hình một bí danh và thư mục trong file httpd.conf nhu sau
cho nền tương ứng của bạn
Alias /images/ “C:/Program Files/Apache Group/Apache2/htdocs/images/”
<Directory “C:/Program Files/Apache Group/Apache2/htdocs/images”>
Sau khi bạn thực hiện những thay đổi này trong file cấu hình Apache, bạn
phải dừng và khởi động instance Apache Bạn sử dụng đồng hồ Apache
trên một hệ thống Windows va script apachectl shell trén cac hé thống
Trang 29à
Như bạn đã thấy trong các mục “PL/SQL đọc các File và ghi các cột CLOB hoặc NCLOBE” và “Đọc các File và ghi cdc c6t BLOB”, ban cé thé
mở một file trong khối PL/SQL mà không cần biết đường dẫn chuẩn tắc Điều này xảy ra bởi vì thủ tục OPEN trong gói DBMS_LOB phân giải nó cho ban Khi ban doc file thông qua thư mục ảo bằng cách sử dụng thủ tục OPEN, bạn phải cung cấp một moduÌe riêng biệt để kết xuất các ảnh trong các trang web Điều này là bắt buộc bởi vì ñle đã được chuyển đổi thành một luông byte thô khi được mở để đọc Bất cứ lúc nào bạn đọc file
dưới dạng một luồng byte, ban phải chuyển đổi file trở lại thành một
ảnh khi kết xuất nó trong một trang web Mục trước “PHP Upload các
File và ghi các cột BLOB” trong chương này thảo luận tại sao việc chuyển
đổi là cần thiết
Bạn nên sao chép fle Raiders3.png từ web site của nhà xuất bản và đặt nó trong thư mục vật lý dành riêng cho nền của bạn ánh xạ sang thư
mục ảo images trong cơ sở dữ liệu Bạn có thể tìm thấy thư mục hệ thống
vật lý đó (hoặc đường dẫn chuẩn tắc) bằng cách viết query sau đây đưới
Bạn cần commit việc cập nhật Nếu bạn quên bước đó thì sau đó bạn
có thể nhận được một lỗi trình duyệt cho bạn biết rằng ảnh không thể được hiển thị bởi vì nó chứa các lỗi Đây là lỗi chuẩn khi cột BETLE trả
về một giá trị rỗng hoặc luỗng rỗng
COMMIT;
Ban có thể kiểm chứng rang file hién hữu và thư mục ảo phân giải
Xác nhận sự tổn tại của file trước khi cố mở nó cung cấp cho chương
trình của bạn thêm khả năng điều khiển Khối nặc danh sau đây cho
bạn xác nhận sự tổn tại của file và nhận được kích cỡ file của nó Hiển nhiên, bạn phải bật SERVEROUTPUT trong SQL*Plus dé xem bat ky két qua:
SQL> SET SERVEROUTPUT ON SIZE 1000000
Sau đó, bạn có thể chạy chương trình khối nặc danh này
DEGLARE
Trang 30Chương 8: Các đối tượng lớn 33
Hàm DBMS_LOB.FILEEXISTS đã được tạo để làm việc trong cả SQL
và PI⁄SQL Vì SQL không hỗ trợ một kiểu dữ liệu Boolean riêng, hàm
trả về 1 khi nó tìm thấy một file và 0 khi nó thất bại Khối nặc danh trả
về kết quả sau đây:
dụng các dấu ngoặc đơn để xác nhận ảnh PNG được kết xuất và các kích
thước pixel của nó
Trong khi cơ sở dữ liệu có thể đọc ñle mà không có bí danh và thư mục
ảo Apache, tiến trình đọc chuyển đổi nó thành một luông byte Điều này
làm cho sự phức tạp của việc tạo một tham chiếu ảnh ngang bằng với
việc đọc một cột BLOB từ cơ sở đữ liệu Bạn sẽ cần chuyển đổi luông byte
trở lại thành một le Điều này đúng cho dù bạn sử dụng C, C++, C#,
Java hoặc PHP để hoàn tất tác vụ.
Trang 3134 Chương 8: Các đối tượng lớn
Hình 8.2 File PNG được kết xuất dưới dạng một ảnh (201 x 300 pixel)
Chương trình ConvertFileToimage.php sau đây trình bày cách bạn
đọc một ñle ngoài thông qua một thư mục cơ sở đữ liệu ảo, chuyển đổi nó
từ một fñle thành một luồng byte và chuyển đổi nó từ một luỗông byte thành một ảnh Chương trình này có thể đọc một file vật lý từ bất kỳ thư mục cơ sở dữ liệu ảo bởi vì chương trình tận dụng catalog cơ sở đữ liệu để phân giải vị trí fñle vật lý
This is found in ConvertFileTolmage.php on the publisher's web site
/ Declare a SQL SELECT statement returning a CLOB
$stmt = “SELECT item_photo FROM item WHERE item_id = :id”; /{ Parse a query through the connection
$s = oci_parse($c,$stmt);
// Bind PHP variables to the OCI types
oci_bind_by_name($s, ':id' $id);
/! Execute the PL/SQL statement
if (oci_execute($s)) { // Return a LOB descriptor and free resource as the value
Trang 32Chương 8: Các đối tượng lớn 35
$data = “ ”; } else {
Chương trình đọc bộ định vị BEILE mà sau đó ngầm định mé BFILE
vào một luồng nhị phân (binary stream) Luồng nhị phân được đọc bởi
phương thức OCI8 readQ được chuyển đổi thành một nguồn tài nguyên file
bởi hàm imagecreatefromstringQ và được chuyển đổi thành một ảnh bởi
hàm imagepngQ Hình 8.3 minh họa ảnh hiển thị từ chương trình này Một phương pháp khác để kết xuất các ñle ảnh đòi hỏi những gì được
gọi là sự ghép đôi cấu trúc giữa các thư mục Apache ảo và thư mục cơ sở
đữ liệu ảo Điều này có nghĩa bạn định nghĩa thư mục ảo cơ sở đữ liệu là
images khi bạn cũng định nghĩa bí danh Apache là images Điều này
cho bạn xây dựng một đường dẫn tương đối đi đến vị trí file ảnh trong
phan td sre cia thẻ img Nó cũng tránh vấn đề chuyển đổi một luồng nhị phân trở lại thành một file
Trang 33sử dụng chương trình này cho những table khác bởi vì nó sử dụng NDS (NÑative Dynamiec SQL) để truy vấn và trả về dữ liệu Việc bao bọc câu
lệnh SELECT bao quanh khối nặc danh sẽ cho bạn dễ dàng thu thập giá
trị trả về Bạn sẽ tìm hiểu thêm về DNS trong chương 11
This is found in get_bfilename.sqi on the publisher's web site
CREATE OR REPLACE FUNCTION get_bfilename ,
Trang 34Chương 8: Các đối tượng lớn 37
Return a scalar query result from a dynamic SQL statement
EXECUTE IMMEDIATE stmt USING QUT locator;
Check for available locator
IF locator IS NOT NULL THEN
dbms_lob.filegetname(locator, dir_alias, file_name);
dir_alias là tên thư mục cơ sở đữ liệu ảo Hàm trả về dir_alias, a / (dấu
gạch chéo tiến), và một tên file cơ sở Giả sử bạn sử dụng file Raiders3.png,
bạn có thể gọi hàm độc lập thông qua một query:
SELECT get_bfilename('ITEM','ITEM_PHOT0', TTEM_]D','1085') AS directory FROM dual;
Nó sẽ trả về:
DIRECTORY
/images/Raiders3.png
Chương trình QueryRelativeBFILE.php sử dụng giá trị trả về
get_bñilename làm phần tử src của thẻ img Điều này chỉ làm việc khi bí
danh Apache cũng trỏ vào cùng một vị trí Query bên trong chương trình
Trang 3538 Chương 8: Các đối tượng lớn
PHP goi dén ham get_bfilename và trả về giá trị dưới dang phan tử thứ
ba trong query Chương trình PHP giả định rằng đường dẫn ảo là chuỗi
duy nhất được trả về với một dấu gạch chéo tiến / đứng trước Có lẽ bạn
muốn khai thác những lựa chọn khác khi bạn có nhiều vị trí ảnh trong một hàng dữ liệu
Sau đây 1A QueryRelativeBFILE.php:
This is found in QueryRelativeBFILE.php on the publisher's web site
<?php
// Declare input variables
{isset($_GET['id'])) ? $id = (int) $_GET['id'] : $id = 1021;
// Call the local function
$stmt = “SELECT item_title
, ttem_desc ' get_bfilename(*ITEM' , STEM_PHOTO','ITEM_ID',:id) FROM item
WHERE item_id = :id”;
// Parse a query through the connection
$s = oci_parse($c,$stmt);
// Bind PHP variables to the OCI types
oci_bind_by_name($s, ‘:id' $id);
// Execute the PL/SQL statement
Trang 36Chương 8: Các đối tượng lớn 39
$data = “ ”; } else {
// Free statement resources
oci_free_statement($s);
// Format HTML table to display BLOB photo and CLOB description
$out = ‘<table border="1" celipadding="5" cellspacing="0">';
Sout = ‘<div style="margin-right:5px;float:left”>’;
Sout = ‘<img src="".$photo.'”>';
Trang 3740 Chương 8: Các đối tượng lớn Trong khi QueryRelativeBFILE.php làm việc cho các giải pháp trên web, nó không làm việc cho các chương trình phía server vốn đòi hỏi tên file chuẩn tắc, đây luôn là một giá trị tuyệt đối Nó ít tốn kém hơn về những nguồn tài nguyên máy bởi vì nó chỉ đọc ñle ảnh và phục vụ nó cho server Apache Những vấn đề với phương pháp này gồm hai phần Thứ nhất, bạn có một nhiệm vụ quản trị để đồng bộ hóa hai thư mục ảo Thứ hai, bất kỳ người dùng có thể xem nguồn và xác định một số thông tin về cấu trúc ñle vật lý của bạn Là một biện pháp phòng ngừa an ninh, chiếm một lượng nhỏ hao phí để xáo trộn (làm ẩn) vị trí của các file là một điều tốt Tương tự, loại bỏ công việc đồng bộ hóa các thư mục ảo Apache và Oracle 11g làm cho việc ứng dụng của bạn bảo trì ít tốn kém hơn Hình 8.4 minh họa kết quả từ mẫu truy vấn ảnh tương đối này
Doc các tên đường dẫn và tên File chuẩn tắc
Phần này minh họa cách bạn có thể chỉnh sửa catalog cơ sở đữ liệu và cho phép những chương trình biên dịch locator BEILE bảo vệ an toàn
tên đường dẫn và tên ñle chuẩn tắc Bạn phải mở các quyển (permis-
gions) để bảo vệ an toàn thư mục ảo được sở hữu bởi người dùng SYS Theo quy tắc chung, bạn nên cho phép truy cập các đối tượng SYS một cách cẩn thận và cho phép chỉ sự truy cập tối thiểu được yêu cầu khi xây
dựng các ứng dụng cơ sở dữ liệu Điều này thường chuyển đổi thành một tiến trình hai bước Thứ nhất, cấp phát đặc quyền từ SYS đến SYSTEM Thứ hai, đóng gói đặc quyền bằng cách viết một hàm thủ tục hoặc thủ
kiện trữ (và cũng đừng quên bao bọc nguồn khỏi những cặp mắt tò
mò)
Hình 8.4 Trang được kết xuất từ chương trình QueryRelativeBFILE php
Trang 38Chương 8: Các đối tượng lớn 41
Dữ liệu được yêu câu để thu thập các đường dẫn chuẩn tắc được tìm
thấy trong khung xem đba_đirectories Người dùng SYSTEM chỉ có các đặc quyển thông qua vai trò SELECT_CATALOG_ROLE vốn giới hạn sự truy cập người dùng SYSTEM chỉ trong khung xem dba_ directories Các đặc quyển vai trò không cho phép một người dùng xây đựng một hàm hoặc thủ tục lưu trữ vốn truy vấn khung xem catalog Do đó, người dùng SYSTEM không thể truy cập khung xem đba_directories thông qua vai trò SELECT_CATALOG_ROLE
Bạn cần kết nối dưới dạng người dùng SY8 có đặc quyền như sau:
§qlplus ' / as sysdba'
Điều này sẽ đòi hỏi password quản trị cơ sở dữ liệu Password này
thường giống với password SYSTEM Sau khi kết nối dưới dạng người dùng SYS, bạn nên cấp pháp đặc quyển cần thiết tối thiểu vốn là SE- LECT trén khung xem cụ thể
Lệnh cấp phát là
GRANT select On dba_directories TO system;
Bây giờ, bạn nên kết nối dưới dạng người dùng SYSTEM và tạo hàm get_directory_path như sau:
This is found in get_directory_path.sq! on the publisher's web site
CREATE OR REPLACE FUNCTION get_directory_path
( virtual_directory IN VARCHARZ )
RETURN VARCHARZ IS
Define return variable
directory_path VARCHAR2(256) := 'C:\’;
Define dynamic cursor
CURSOR get_directory (virtual_directory VARGHAR2) IS
SELECT directory_path FROM sys.dba_directories WHERE directory_name = virtual_directory;
Define a local exception for name violation
Trang 3942 Chương 8: Các đối tượng lớn
CLOSE get_directory;
Return filename
RETURN directory_path;
EXCEPTION WHEN directory_name THEN RETURN NULL;
END get_directory_path;
/
get_directory_path lấy một thư mục ảo làm tham số hình thức duy
nhất của nó Nó sử đụng thư mục ảo để tìm đường dẫn chuẩn tắc Bạn có thể sử dụng thủ tục FILEGETNAME trong gói DBMS_LOB để tìm thư mục ảo Nó trả về đường dẫn chuẩn tắc và tên file cơ sở cho bất kỳ
locator BFILE
get_canonical_bfilename st dung NDS (Native Dynamic SQL) dé tra
vê một cột BEILE Bằng cách này bạn viết một hàm cho bất kỳ số của các cột BEFILE có thể có Vấn để duy nhất với ví dụ này là nó phụ thuộc
vào một khóa chính một cột cho tất cả table đích Bạn nên biên địch
hàm get_canonical_bfilename trong schema SYSTEM sau khi ban da
bién dich ham get_directory_path
This is found in get_canonical_bfilename.sql on the publisher's web site
CREATE OR REPLACE FUNCTION get_canonical_bfilename
Trang 40Chương 8: Các đối tượng lớn 43
Define a local exception for size violation
Run dynamic statement
EXECUTE IMMEDIATE stmt USING OUT locator;
Check for available locator
\F locator IS NOT NULL THEN
dbms_lob.filegetname(locator, dir_alias, file_name);
END IF;
Check operating system and swap delimiter when necessary
IF operating_system <> ‘WINDOWS' THEN
delimiter := ‘/';
END IF;
Create a canonical filename
file_name ‘= get_directory_path(dir_alias) || delimiter I 1 file_name; Return filename