1. Trang chủ
  2. » Công Nghệ Thông Tin

GIÁO TRÌNH HD LÝ THUYẾT VÀ KÈM THEO BT THỰC HÀNH ORACLE 11G: TẬP 2

380 506 6
Tài liệu được quét OCR, nội dung có thể không chính xác
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 380
Dung lượng 15,73 MB

Nội dung

trình bày các điểm cơ bản về pl/sql, lập trình pl/sql và lập trình nâng cao pl/sql.

Trang 2

Giáo trình

Hướng dẫn Lý thuyết và

Trang 4

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

hanh ORACLE 11g” được biên soạn toàn diệ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 dung PL/SQL manh được điều khiển bởi cơ sở đữ 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:

Phan I: Cac điểm cơ bản uê 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 cia PL/SQL, va giải thích các khái niệm về ngữ nghĩa, các kiểu đữ liệu, các cấu trúc điều khiển và sự quản lý lỗị

Phân II: Lập trình PLJSQL

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 Oraclẹ

Phần III: Lép trinh néng cao PL/SQL

Với phần nay, ban đọ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ệụ

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 on

Trang 5

Chương 8: Các đối tượng lớn

PHAR OL (62 theo tap 1/

Ldap trinh PL/SQL

Chương 8: Gác đối tượng lớn

Phương 9: Gác gói (Package) Chương 10: Các Trigger

Trang 6

8 Chương 8: Các đối tượng lớn

CHUONG 5

CÁC đối TượNg lớn

phép lưu trữ text, hình ảnh, nhạc và video trong cơ sở dữ liệụ

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 (large obJect) Bây giờ chúng

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ở dữ liệụ 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ệụ 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ở dữ liệu dưới dạng các cột

BLOB hoặc bên ngoài cơ sở đữ liệu dưới dạng cột BEILE (binary file) Các cột BEFILE lưu trữ một locator trỏ sang vị trí vật lý của một file bên

ngoàị

Chương này giải thích cach su dung PL/SQL để làm việc với các kiểu dữ liệu LOB khác nhaụ Chương bao gồm những chủ điểm sau đây:

m Các đối tượng lớn ký tự

PL/SQL đọc các file và ghi các cột CLOB hoặc NCLOB

Upload các CLOB lên cơ sở dữ liệu Các đối tượng lớn nhị phân

PL/SQL doc cac file và ghi các cột BLOB Upload cac BLOB lên cơ sở dữ liệu

SecureFiles

Trang 7

Chương 8: Các đối tượng lớn 9 mã Các BFILE ngoài

™ Tao va st dung cac thu muc ao (virtual directories) m Goi DBMS_LOB

Những khái niệm chi phối cách sử dụng các kiểu đữ liệu BLOB, CLOB,

và NCLOB thì rất tương tự Các kiểu dữ 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 fñle Adobe PDF (Portable Docu- ment Format), anh va phim (movie) bên trong cơ sở đữ liệụ Việc truy

cập và hiển thi cdc file BLOB dugc 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 SecureEiles 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 đữ liệu BFILẸ 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 ñlẹ Gói DBMS_LOB đứng sau cùng bởi vi

không phải hàm nào cũng cần thiết để hướng đẫ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 đổi tượng lớn ký tự: Các kiểu dữ liệu CLOB và N€L0B |]— —— — — — m— —— Gm BHHỊm DƯƠNG HT” VUHHƠNNH ee ee ee i A-=e= =m-mm

Các kiểu dữ liệu CUOB và NCLOB định nghĩa một cột trong một table hoặc nested tablẹ Nó có kích cỡ vật lý tối đa giữa 8 và 128 terabytes Kiểu đữ 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 tablẹ Chỉ deseriptor 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 SGẠ Vùng làm

việc này cho phép cuộn qua nội dung và ghi các cụm đữ liệu mớị Một số

nội dung tham khảo sử dụng thuật ngữ deseriptor để nói đến locator (bộ

định vị BLOB, CLOB và NGLOB, nhưng sử dụng locator khi làm việc với các BFILE ngoàị Tài liệu Oraele 11g bắt đâu gọi cả hai là các locator

Trang 8

10 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 déi tượng một cách ngầm định hoặc tường minh Ban có thể xây đựng một biến CUOB 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 CUOB 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 PI/

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

một lúc

Các ví dụ sau đây xem lại cách bạn khai báo một biến CLOB:

var1 GLOB; Declare a null reference to a CLOB vari CLOB := empty_clob(); Declare an empty CLOB

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ớt hạn chỉ trong các trạng thái NULL hoặc NOT NULL Cac 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 NCLUOB 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 dữ 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_cÌobQ trong cột item_desc cua table item:

~ This is found in create_storẹsql on the publisher's web sitẹ INSERT INTO item VALUES

( item_s1.nextval

, — ASIN: B000030XI1'

(SELECT common_lookup_id FROM common_lookup

WHERE common_lookup_type = 'DVD_WIDE_SCREEN’)

‘Harry Patter and the Sorcer's Stone’

, ‘Two-Disc Special Edition’ , empty_clob()

Trang 9

Chươ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_desc = 'Harry Poter 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_¡d FROM common_lookup

WHERE common_lookup_table = 'ITEM'

AND common_lookup_column = 'ITEM_TYPE‘

AND REGEXP_LIKE(common_lookup_type,'*(DVDIVHS)*'))

Bang 8.1 Các trạng thái dif li€u BLOB, CLOB va NCLOB

Trang thai Mô tả

NULL Cột trong một hàng table chứa một giá trị

rong (null)

Empty Cột chứa một locator (hodc descriptor) LOB

vốn là một instance réng Ban có thể kiểm tra một lớp rỗng bằng cách gọi các hàm DBMS_LOB.GETLENGTH Hàm trả về giá trị zero cho một cột BLOB, CLOB hoặc NCLOB rỗng Populated Cột chứa một locator LOB và một lệnh gọi đến hàm DBMS_LOB.GETLERNGTH

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 UPDATTE 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ử đụ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 UPDATTE đế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 đữ liệu vào cột sau lần ghỉ ban đầụ 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 filẹ Sau đó, nó tải

dữ liệu sang các cụm 32.767 bytes qua thử tục

Trang 10

12 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 ma bạn có thể thêm vào các câu lệnh DML INSERT

hoặc UPDATTẸ Bạn biến đổi các câu lệnh INSERT hoặc UPDATE thành

các lệnh gọi hàm bằng cách thêm mệnh để nàỵ

Mệnh đề RETURNING khai báo một tham số chế độ OUT hình thức

đưới dạng đích của vị ngữ INTỌ Mệnh đề 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áọ 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 gidi han kich cd cha SQL va PL/SQL Hinh 8.1 minh hoa tién trình về

cách làm việc cha ménh dé RETURNING INTỌ

Bạn có khả năng ghi sang cột CLOB hoặc NCLOB từ đầu một lệnh TINSERT hoặc UPDATE (vốn mở nguần) cho đến cuối phạm vỉ 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 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 khối độc lập vốn cũng có thể commit việc ghị

Mệnh để RETURNING nhận dạng

tham số hình thức bằng cách nao nó

sang một tên cột Nó cũng xác lập chế độ hoạt động sang chế đè IN va OUT

(hoặc chuyển theo tham chiếu) Đầu vào tham chiếu Cơ sở Độ định vị khứ hồi (Retum Locator) dữ liệu

Đầu ra tham Mệnh để INTO gán một biến cục

chiếu bộ dưới dạng tham số thật sự của

một lệnh gọi hàm để tạo một nối

kết cơ sở dữ liệụ Nối kết cho bạn ghi dữ liệu sang mat locator BLOB hoac CLOB trong mét giao tac

Trang 11

Chươ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 cia ménh dé RETURNING INTO lic dau vung 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 và sau đó nó trả về locator

qua câu lệnh RWTURNING 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 OỤT 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 INSERIT, 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 ví giao tác Bạn có thể thêm vào hoặc thay thế

nội dung duge tré vao locator trong phạm vì của giao tác nàỵ Thừa kế kiểu dữ liệu của cột được tham chiếụ INSERT wire table nts bmn_name2[,column_namée(n+1)}}) ) Xác lập giá trị Xác lập tên cột ban đầụ biến cục bộ Câu lệnh UPDATE

Câu lệnh UPDATE xác lập giá trị cột CLOB bang ham EMPTY_CLOB

và sau đó nó trả về column locator (bộ định vị cột) qua mệnh để RE- TURNING INTO vào 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 OUT Như câu lệnh INSERIT, sự

Trang 12

14 Chương 8: Các đối tượng lớn

Xác lập giá trị

UPDATE table_name catia: đầụ SET c namel = co1u value1 Thừa kế kiểu dữ

liệu của cột được Xác lập tên

tham chiếụ biến cục bộ

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ñile 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àị Mục nhỏ đầu tiên hướng dẫn bạn đọc các file 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ệụ Mục thứ nhất thảo luận một giải pháp server cơ sở đữ liệu và mục thứ hai cung cấp bạn một

thi tuc PL/SQL để hỗ trợ việc upload CLOB hoặc NCLOB từ xạ PL/SQL ñụt cát File và ghi các cột CLOB hodc 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 ban chay script create_user.sql từ web site của nhà xuất bản Thư mục ảo là một bí danh

thư mục nội tại trồ vào một đường dẫn

Trong ví dụ này, bạn 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 ảọ Các lệnh sau đây làm việc trên hệ điều hành cụ

thể của bạn:

Linux hoặc Unix

Trang 13

Chương 8: Các đối tượng lớn 15

Windows

CREATE DIRECTORY generic AS 'C:\Windows\temp';

Sau 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 DIRECTORY generic TO plsql;

Các bước tiếp theo là đọc ñle 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 chọ Bằng cách này, bạn có thể cắt và đán nó ngay vào các

ting dung cia ban Vi du st dung NDS (Native Dynamic SQL) Ban nén

tham khảo chương 11 nếu bạn tò mò về những cơ cấu của ND8

Thủ tục load_clob_ftom_ñle sau đây minh họa cách làm điều này:

-= Thịs is found ìn load_eloh_from _filẹsql an the publisher's web sitẹ

CREATE OR REPLACE PROCEDURE load_clob_from_file ( src_file_name IN VARCHAR2 , table_ name IN VARCHAR2 , Column_name IN VARCHAR2 , primary_key_name INÑ VARCHAR2 , primary_key_value IN VARCHARZ ) |S Define local variables for DBMS_LOB.LOADCLOBFROMFILE procedurẹ des_clob CLOB; src_clob BFILE := BFILENAME('GENERIC' sre_file_name); des_offset NUMBER := 1; src_offset NUMBER := 1; ctx_lang NUMBER := dbms_lob.default_lang_ctx; warning NUMBER; Define a pre-reading sizẹ src_clob_size NUMBER: Define local variable for Native Dynamic SQL stmt VARCHAR2(2000); BEGIN

Opening source file is a mandatory operation

IF dbms_lob.fileexists(src_ctob) = 1 AND NOT dbms_lob.isopen (sr¢_clob) = 1 THEN

src_clab_size := dbms_lob.getlength(src_clob);

Trang 14

16 Chương 8: Các đối tượng lớn END IF;

Assign dynamic string to statement stmt := ‘UPDATE ‘I | table_name |’ '

|| ‘SET ‘I | colurn_name } | ‘ = empty_clob() ‘

1) ‘WHERE 'I | primary_key_name ||‘ = 1Í ”" | 1 primary_key_vaiuel |" * } | ‘RETURNING ‘11 column_name | 1 * INTO :tocator’;

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 , src_bfile => src_clob , amount => dbms_lob.getlength(src_clob) , dest_offset => des_offset , Sr€_0ffset => src_ 0ffset , bfile_csid => dbms_lob.default_csid , lang_context => ctx_lang , warning => warning ); dbms_lob.close(src_clob):

IF src_clob_size = dbms_lob.getlength(des_clob) THEN

$IF $$DEBUG = 1 $THEN dbms_output.put_line(‘Success!'); $END COMMIT; ELSE SIF $$DEBUG = 1 $THEN dbms_output.put_tine('Failurẹ’); $END RAISE dbms_lob.operation_failed; END IF; END load_clob_from_fite; /

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

Trang 15

UP-Chương 8: Các dối tượng lớn 17 DATE động xác lập cột CLOB sang một empty_clob() Sau đó, câu lệnh

UPDATE trả về cột được ấn định vào một biến đầu rạ Biến liên kết

locator 1a bién dau ra trong cau lénh NDS Ban gán locator CLOB sang biến des_clob khi câu lệnh NDS chạỵ

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 le nguồn và liên kết với một bộ định vị 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 đến thú tục LOADCLOBFROMFILE chuyển nội dung của ñle mở sang bộ định vị CUOB Hoạt động đọc và ghi này không bị giới hạn xử lý 32.767 byte của PL/SQL, Nó cũng là một phương pháp để đọc trực tiếp các cụm ñle lớn vào các cột CLOB Các giá trị dịch

chuyển ñle nguồn (src_offset) và các giá trị dịch chuyển cột CLOB đích

(dest_offset) cho bạn phân tích cú pháp các cụm từ file và đặt chúng

trong cột CLOB Tất cả 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 UPDATTE)

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_trom_filẹsql on the publisher's web sitẹ 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_table = ‘ITEM’

AND common_lookup_column = 'ITEM_TYPÉ

AND REGEXP_LIKE(common_lookup_type,’“(dvdlvhs)*','í)))

LOOP

Call reading and writing CLOB procedurẹ

load_clob_from_fite( src_file_name => 'LOTRFellowship.txt' , table_name => ‘ITEM’

; 00Ìlumn_ name => 'ITEM_DESG' , Drimary key_name => 'TEM_!D'

, primary_key_value => TO_CHAR(ịitem_id));

Trang 16

18 Chương 8: Các đối tượng lớn END;

/

Lệnh gọi đến thủ tục load_clob_from_le được thực hiện cho mọi giá trị item_id đáp ứng quy tắc nghiệp vụ được xác định bởi phép tim 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 va VHS noi 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 hoac VHS

Bạn có thể chạy định dạng và query sau đây để xác nhận rằng ba

hang bây giờ có các cột CLOB với các luồng dữ liệu dà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 sizẹ SELECT _ item_id ; item_title dbms_lob.getlength(item_desc) AS “SIZE” FROM item WHERE dbms_iob.getlength(item_desc) > 0;

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 cdc CLOS lén cd 30 da lidu

Nhu PL/SQL, cdc ngén ngi 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à ghi các cụm lớn thông qua các

chương trình bên ngoàị

Giải pháp sau đây tạo một thủ tục PL/SQL có khả năng hỗ trợ bất kỳ

Trang 17

Chương 8: Các đối tượng lớn 19

This is found in create_web_clob_loading.sql on the publisher's web sitẹ

CREATE OR REPLACE PROCEDURE web_load_clob_from_file ( item_id_in 1N NUMBER , descriptor IN OUT CLOB ) IS BEGIN A FOR UPDATE makes this a DML transaction UPDATE item

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ừ file

chương trình từ xạ Có ba tính năng chính trong thủ tục nàỵ 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ế độ TN

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 COMMITT 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àị

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àị

Các đổi tượng lớn nhị phân: Kiểu dữ liệu BLOB

Kiểu đữ liệu BLOB có thể định nghĩa một cột trong một table hoặc nested tablẹ Như kiểu đữ liệ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

nhu cac anh, track nhac, phim (movie) hodc cac file Portable Document Format (PDF) Muc nay xem xét cách ban có thể upload, ghi và đọc các kiểu dữ liệu BLOB,

Gh hic

Như kiểu du liẹu CLOB, kiểu dỡ liẹua BLOB có kích cỡ cội lối đa được xác lập

bại lham số khải lạo cơ số da liệu db_ Hock_ sizẹ Kch cỡ khái SKÐ mạc định

giới han mot BLOB chi long 8 lerabules

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

Trang 18

20 Chương 8: Các đối tượng lớn

handle BLOB la 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àị 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 đự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 dữ liệu BLOB

Các ví dụ sau đây xem lại cách bạn khai báo một biến BLOC:

var1 BLOB; Declare a null reference to a BLOB var} BLOB := empty_blob{); Declare an empty BLOB

var2 BLOB := '43'} | '41'1 1 '52'; Declare a hexadecimal BLOB for CAR

Có hai cách để tập hợp lại các cột BLOB Ban có thể tải một file phía server bằng cách gọi các thủ tục OPEN, LOADBLOBFROMFILE và CLOSE được tìm thấy 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 thư

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 nhaụ Chúng cũng không bi giới hạn chỉ trong cdc trang thai NULL ho&ac NOT NULL Cac BLOB, CLOB va NCLOB 1a NULL, empty, hodc populated nhu dugc trinh bay truéc d6 trong bang 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àỵ 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 UPDATẸ Bạn biến

đối các câu lệnh INSERT hoặc IPDATE thành các lệnh gọi hàm bằng

cách bổ sung mệnh đề nàỵ

Mệnh dé RETURNING khai bdo mét tham số chế độ OUT hình thức

dưới dạng đích của vị ngữ INTỌ Ménh dé neo (anchor) mét b6 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áọ 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 họa tiến (trình về cách

làm việc của mệnh đề RETURNING INTỌ

Bạn 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

COMMIT hoặc ROLLBACK kết thúc phạm vi giao tác bên trong một

Trang 19

Chươ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 dữ liệu CLOB và NCLOB nhưng đối với phương thức tạo empty_blỏb() Từ khóa RETURNING của ménh dé RETURNING INTO nghia 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 Ban 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 dé

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 tác nàỵ Thừa kế kiểu dữ liệu của cột được tham chiếụ INSERTJINTO table_name (column _namel{ ¡co1lmn_name2[, column name (n+1)]] ) emp X Binh Ú ti 294 ›_value2[,coIumn value (nt1)}] ) Xác lập giá trị Xác lập tên cột ban đầụ biến cục bộ Câu lệnh UPDATE

Cau lénh UPDATE giả định column_name2 là mot! kiểu dữ ligu 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 Như câu

lệnh INSERT, cau lénh UPDATE bắt đầu một phạm vi giao tác Bạn có

Trang 20

22 Chương 8: Các đối tượng lớn

Xác lập giá trị UPDATE table name cột ban đầụ

SET column_namel = columt valuel Lz column_name (n+1) column_value(nt1)]] ) RETURNING nto ii 1 e "Thừa kế kiểu dữ

liệu của cột được Xác lập tên

tham chiếụ 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/ S§QL cho dữ liệu ký tự và ghi chúng sang các cột BLOB Mục thứ nhất, mỉnh họa cách ghi module PL/SQL để tải 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 dưới dạ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 để minh họa cách nó được upload, được ghi sang cơ sở dữ liệu và

được kết xuất trong một trang web như thế nàọ PL/SQL figc cac File va ghi cac cot 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 P1/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 doc

các File và ghi các cột CLOB hoặc NCLOB”, thư mục cơ sở dữ 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ờị

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 ảọ 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 ở đâỵ Các lệnh sau đây làm việc

phụ thuộc vào hệ điều hành cụ thể:

Linux hoặc Unix

CREATE DIRECTORY generic AS '/tmp':

Windows

Trang 21

._ Chươ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 plsal Cú pháp là

GRANT READ ON DIRECTORY generic TO plsql;

Bước kế tiếp là đọc file và ghi dữ liệu sang cột BUOB 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 chọ Ví dụ nay sif dung NDS (Native Dynamic SQL), tham khao néi

dung được đề cập trong chương 11

Thủ tục load_blob_from_fñle sau đây minh họa cách làm điều này:

Thỉs is found in load_blob_fram_filẹsql an the publisherˆs web sitẹ CREATE OR REPLACE PROCEDURE load_blob_from_file ( src_file_name IN VARCHAR2 , table_name IN VARCHAR2 , column_name IN VARCHAR2 , primary_key_name !N VARGHAR2 , primary_key_value IN VARCHARZ ) IS Define local variables for DBMS_LOB,LOADBLOBFROMFILE procedurẹ des_blob BLOB; src_blob BFILE := BFILENAME('GENERIC’,src_file_name); des_offset NUMBER := 1; src_offset NUMBER := 1; Define a pre-reading sizẹ src¢_blob_size NUMBER; Define local variable for Native Dynamic SQL stmt VARCHAR2(2000); BEGIN

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_fob.getlength(src_blob); dbms_lob.open(src_blob, DBMS_LOB.LOB_READONLY); END IF; Assign dynamic string to staternent stmt := ‘UPDATE 1 I table_name I I ' '

}1 ‘SET ‘I 1 column_name | 1° = empty_blob() '

II "WHERE l1 l primary_key_name | | ' = ‘11 ''" | | primary_key_valuel |‘ '

Trang 22

24 Chương 8: Các đối tượng lớn Run dynamic statement

EXECUTE IMMEDIATE stmt USING OUT des_blob;

Read and write file to, BLOB

dbms_iob.loadblobfromfile( dest_lob => des_blob , src_bfile => src_blob , amount => dbms_lob.getlength(src_btob) , dest_offset => des_offset , src_offset => src_offset ); Close open source filẹ dbms_lob.close(sre_blob); Commit writẹ

IF src_blob_size = dbms_lob.getlength(des_blob) THEN $IF $$DEBUG = t $THEN dbms_output.put_line(‘Success!’); SEND COMMIT; ELSE SIF $$DEBUG = 1 $THEN dbms_output.put_line('Failurẹ‘); SEND RAISE dbms_lob.operation_failed; END IF; ENO load_blob_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 BLOB và một khóa chính của cột Sau khi kiểm chứng rằng fñle hiện hữu và không mở, lệnh gọi thú tục DBMS_LOB.OPEN mở ñile ngoài và đọc nó vào một kiểu đữ liệu BFILẸ 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 fñlẹ Hàm

BFILENAME trả về mật tên ñile chuẩn tắc Câu lệnh UPDATTE độ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

rạ Biến liên kết :loeator 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ạỵ Kích cỡ fđle ngồ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

Trang 23

Chương 8: Các đối tượng lớn 25

Tất cả hành động trước đọc fñle 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 LOADBLOBFROMEFILE chuyển nội dung của ñle mở sang bộ định vị BLOB Hoạt động doc va 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 dich (dest_offset) cho ban

phân tích cú pháp các cụm từ file và đặt chúng trong cột BLOH 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

ñle 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 load_blob_from_filẹsq! on the publisher's web sitẹ BEGIN FOR i IN (SELECT item_id FROM item WHERE _iterm_title = ‘Harry Potter and the Sorcerer''s Stone’ AND item_type IN (SELECT common_lookup_id FROM pommon_lookup

WHERE common_lookup_table = ‘ITEM’

AND common_lookup_column = ‘tTEM_TYPÉ

AND REGEXP_LIKE(common_lookup_type,’“(dvdivhs)*’,‘í))) 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_ID’ , primary_key_value => TO_CHAR(ịitem_id) ); END LOOP; END; /

Lénh goi dén thu tuc load_blob_form_file được thực hiện cho mọi giá

Trang 24

26 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 hang bây giờ có các cột BLOB với các luồng đữ 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 sizẹ SELECT item_id item_title dbms_lob.getlength{item_blob) AS “SIZE" FROM item WHERE dbms_lob.getlength(item_blob) > 0; Nó tạo ra ba hàng sau đây:

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

Upload cac BLOB lên cơ sở dữ liệu

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 các cộệt 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 ñile 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 Oracle 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 đạng các cụm

This is found in create_web_blob_loading.sqi on the publisher's web sitẹ

CREATE OR REPLACE PROCEDURE web_load_blob_from_file { item_id_in IN NUMBER

, descriptor IN OUT BLOB ) IS

Trang 25

Chương 8: Các đối tượng lớn 27

A FOR UPDATE makes this a OML transaction UPDATE item

SET itern_blob = 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àỵ 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 đề RETURNING INTO 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 bi khéa và phạm vi giao tác DML mở cho các chương trình web

ngoàị

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ở dữ liệu và thông qua các chương trình bên ngoàị

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 và NCLOB SecureFiles cho phép mã hóa, nén và hủy sao chép các LOB Chúng làm việc theo nguyên tắc Transparent Data Encryption (TDE) va sử dụng một Oracle Wallet làm khóa mã hóa,

Gi che

ee ee a ee ee eee ee ee ee Le

TDE cho bạn chọn một thuật tố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

HB AES192 (default) @ AES256

Bạn có thể kiểm tra xem instanee có được cấu hình để làm việc với SecureFiles hay không bằng cách truy vấn khung xem (view) véparameter

Query và định dạng SQL*Plus là

Trang 26

28 Chương 8: Các đối tượng lớn

COLUMN value FORMAT A14

SELECT name, value FROM v$parameter WHERE name LIKE ‘db_securefie’;

Ít ra bạn nên có các dong sau đây dé lam viéc vdi SecureFiles:

db securefile PERMITTED|

Bước tiếp theo đòi hỏi bạn thiết lập một password mã 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 hodc Unix

# SORACLE_HOME/bin/owm

Windows

C:> %ORACLE_HOME%\bin\launch.exe “oracle_canonical_path\bin” owm.cl

Lệnh menu có lẽ đễ hơn Nó là: Start | Programs | Oracle - Oracle

Home ! Integrated Management Tools | Wallet Manager Bén trong

Wallet Manager, ban cé thé tao một khóa mã hóạ Bạn nên lưu nó sang vị trí mặc định, đó là Linux hodc Unix /etc/ORACLE(WALLETS/username Windows %USERPROFILE%\ORACLE\WALLETS

%USERPROFILE% anh xa sang tén user trén mét nén Windows Trên một số nên, bạn phải đặt các hướng dẫn vào file sqlnet.ora mà bạn sẽ tìm thấy trong thư mục /network/admin (các dấu gạch chéo ngược cho

Windows) cua Oracle Homẹ Tén file wallet 1a ewallet.p12 Ban nhập các dòng sau đây trong file sqlnet.ora:

ENCRYPTION_WALLET_LOCATION = (SOURCE =

(METHOD = FILE)

Trang 27

Chươ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 SecureFiles như

CREATE TABLESPACE securefiles

DATAFILE ‘<canonical_path>\sec_filẹ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 fñle 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 AĐ (sec_fite CLOB) LOB(sec_file)

STORE AS SECUREFILE sec_file (TABLESPACE securefile);

Bay giờ bạn có thể thay đổi và mã hóa cột:

ALTER TABLE item MODIFY LOB(sec_file) (ENCRYPT 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 dữ liệu BFILE

Kiểu đữ liệu BFILE (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ị BFILE là những kiểu đữ liệu LOB read-only (chỉ doc) va dude luu trữ bên ngoài cơ sở đữ liệụ Không giống như các kiểu đữ 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 đữ 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), cdc file PDF, tai liéu

Microsoft Office và movie QuickTimẹ 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ả đle ngồi trong một cột BETLẸ Nói chung, chúng được phục vụ cho các khách hàng Ïnternet hoặc intranet thông qua các trình

duyệt web Các trình đuyệ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, dié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ị

Trang 28

30 Chương 8: Các đối tượng lớn

BFILE ngoài như thế nàọ Đồ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 ñle nguồn

BFILE ngoaị

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 ngồ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 file bên trong trong cơ sở dữ liệụ

Tao va sii dung cdc thu myc 40

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 co sé

di 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 hoặc vai trod SELECT_CATALOG_ROLẸ Theo

mặc định, người dùng SYSTEM truy cập khung xem dba_directories théng qua vai tro SELECT_CATALOG_ROLẸ

Bạn thường tạo các thư mục ảo đướ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ò DBẠ

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ữụ 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 Unix 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 SVSTEM và định nghĩa một thư mục ảnh ảọ 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 hodc Unix

CREATE DIRECTORY images As '/varAwww/htmi/images’;

Windows

Trang 29

Chương 8: Các đối tượng lớn 31

Sau khi tạo thư mục ảo, dưới dạng nguéi dang SYSTEM ban can cap 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 DIRECTORY images 10 plsal;

Các bước kế tiếp thường bao gồm tạo một bí danh (alias) và thư mục ao trong file Apache httpd.conf Nếu bạn muốn cấu hình bí đanh 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ý đo rất tốt để xác lập các bí danh và thư mục ảo trong Apachẹ 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 Oraclẹ

Có quy tac bdi vi tha tue FILENAME cua gói DBMS_LOB cung cấp chỉ 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 ñle 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ở dữ liệụ

Tạo một bí danh và thư mục ao 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ớị Bạn cần cấu hình một bí danh và thư mục trong file httpd.conf như sau

cho nền tương ứng của bạn Linux Alias /images/ “/var/www/html/images” <Directory “Avar/www/html/images”> Options None AilowOverride None Order allow,deny Allow from all </Directory> Windows

Alias /images/ "C:/Program Files/Apache Group/Apache2/htdocs/images/” <Directory “C:/Program Files/Apache Group/Apache2/htdocs/images”> Options None AltowOverride None Order allow,deny Allow from all </Directory>

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 Apachẹ Bạn sử dụng đồng hồ Apache

trên một hệ thống Windows và soript apachectl shell trên các hệ thống

Linux hoadc Unix

Trang 30

32 Chương 8: Các đối tượng lớn

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 NCLOB” và “Đọc các File và ghi các cột BLOB”, bạn có thé

mé mét file trong khéi PL/SQL ma không cần biết đường dẫn chuẩn tắc

Điều nay xay ra bởi vì thủ tục OPEN trong gói DBMS_LOB phân giải nó

cho bạn Khi bạn đọc file thông qua thư mục ảo bằng cách sử dụng tha tục OPEN, bạn phải cung cấp một module 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ì file đã được chuyển đổi thành một luỗng byte thô khí được mở để đọc Bất cứ lúc nào bạn doc file đưới dạng một luồng byte, ban phải chuyển đổi ñle 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 Fie 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 le 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ở đữ liệụ 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 dưới

dang người dùng SYSTEM:

SELEGT * FROM dba_directories WHERE directory_name « 'IMAGES`;

Sau khi ban đã cấu hình thư mục ảo và đặt fñle Raiders3.png trong

đúng thư mục, bạn chèn một locator BEILE vào một cột cơ sở đữ liệu để

test Bạn có thể sử dụng câu lệnh sau đây để cập nhật một cột bằng một

locator BFILE: UPDATE item

item_photo = BFILENAME('IMAGES'’, Raiders3.png') WHERE item_id = 1055;

Bạn cần commit việc cập nhật Nếu bạn quên bước đó thì sau đó ban

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ỗị Đây là lỗi chuẩn khi cột BFLLE trả về một giá trị rỗng hoặc luồng rỗng

COMMIT;

Bạn có thể kiểm chứng rằng file hiện hữu và thư mục ảo phân giảị

Xác nhận sự tổn tại của ñle 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 ñle 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 để xem

bất kỳ kết quả:

SQL> SET SERVEROUTPUT ON SIZE 1000000

Sau đó, bạn có thể chạy chương trình khối nặc danh nàỵ

Trang 31

Chương 8: Các đối tượng lớn 33 DECLARE tile_locator BFILE; BEGIN SELECT item_photo iNTO file_locator FROM item WHERE item_id = 1055; IF dbms_lob.fileexists(file_locator) = 1 THEN dbms_output.put_line(‘File is: ['l | dbms_lob.getlength(file_locator)| | lì ELSE dbms_output.put line('No file found.); END IF; END; /

Hàm DBMS_LOB.FILEEXISTS đã được tạo để làm việc trong cA 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 fñle và 0 khi nó thất bạị Khối nặc danh trả về kết quả sau đây:

File is: [126860)

Nếu bạn đã thêm thành công một bí danh images và một thư mục ảo

vào một fñle Apache httpđ.conf, bạn có thể hiển thị fñle bằng cách sử dung URL sau đây:

http://<hostname>.<domain_name>/images/Raiders3.png

Hinh 8.2 minh họa file ảnh được tìm thấy bởi URL Bạn nên chú ý sự khác biệt và sự tương đồng giữa các tiêu đề trình duyệt của các hình 8.2 và 8.3, Hình 8.3 cho biết một chương trình PHP đã tạo ra trong ảnh

trong khi hình 8.2 cho biết một ảnh đã được đọc từ server Cả hai sử 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ở đữ 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 bytẹ Đ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ệụ Bạn sẽ cần chuyển đổi luông byte

trở lại thành một filẹ Điều này đúng cho dù bạn sử dụng C, C++, Cử,

Trang 32

34 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 ConvertFileTolmagẹphp sau đây trình bày cách bạn đọc một file ngồi thơng qua một thư mục cơ sở dữ liệu ảo, chuyển đổi nó

từ một 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ở dữ liệu để

phân giải vị trí file vật lý

This is found in ConvertFileTolmagẹphp on the publisher's web sitẹ

<?php

// Return successful attempt to connect to the databasẹ if ($c = @oci_new_connect(“‘plsq!”,"plsql”,"orcl”)) {

// Declare input variables

(isset($_GET[‘id'])) ? $id = (int) $_GET[‘id'] : $id = 1021;

// 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)) {

Trang 33

Chương 8: Các đối tượng lớn 35 while (oci_fetch($s)) { for ($i = 1;$1 <= oci_num_fields($s);$i++) it (is_object(oci_result($s,$i))) { if ($size = oci_result($s,$i)->size()) { $data = oci_result($s,$i)->read($size); } else $data = “&nbsp;"; } else { if (oci_fietd_is_aull($s,$i)) $data = “&nbsp;"; else $data = oci_resutt($s,$i); }} // Free statement resources oci_free_statement($s); // Print the header first header('Content-type: image/png’); imagepng{imagecreatefromstring({$data)); } // Disconnect from databasẹ oci_close($c); } alse { // Assign the OCI error and format double and single quotes SerrorMessage = oci_error(); print htmlentities($errorMessage|'message’])."<br />”; } ?>

Chương trình doc bé dinh vi BFILE ma sau d6 ngam dinh mé BFILE vào một luéng nhi phan (binary stream) Luéng nhi phan duge doc bởi phương thức OC18 read() đượ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 imagepngỌ Hình 8.3 minh hoa ảnh hiển thị từ chương trình nàỵ

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 ảọ Đ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 phần tử sre của thẻ img Nó cũng tránh vấn đề chuyển đổi một luồng nhị

Trang 34

36 Chương 8: Các đối tượng lớn Hình 8.3 Cột BFILE được kết xuất dưới dạng một ảnh PNG (201 x 300 pixel)

Bước đầu tiên trong việc hoàn thành loại phương pháp này đòi hỏi

một hàm wrapper bao quanh thử tục EIUEGETNAME của gói DBMS_LOB Hàm get_bñlename phân phối wrapper đó Bạn có thể tái sử dụng chương trình này cho những table khác bởi vì nó sử dụng NDS

(Native Dynamic SQL) để truy vấn và trả về dữ liệụ Việc bao bọc câu lệnh SELECT bao quanh khối nặc danh sẽ cho bạn 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_bfilenamẹsql on the publisher's web sitẹ

Trang 35

Chương 8: Các đối tượng lớn 37 directory_num EXCEPTION; PRAGMA EXCEPTION_INIT(directory_num,-22285): BEGIN Wrap the statement in an anonymous block to create and OUT mode variablẹ stmt := ‘BEGIN ' [1 ‘SELECT ‘I | column_name ||‘ ’ II ‘INFO :locator ' |I ‘FROM '11 table_name I ! ' ˆ |I_"WHERE 'I | primary_key_namel I ' œ '1 | '"*1 | primary_key_valuel 1( 'END;';

Return a scalar query result from a dynamic SQL statement

EXECUTE IMMEDIATE stmt USING OUT locator;

Check for available locator IF locator 1S NOT NULL THEN

dbms_lob.filegetname(locator, dir_alias, file_ name): END IF; Return filenamẹ RETURN delimiter! | LOWER(dir_alias)! | delimiterl | file name; EXCEPTION WHEN directory_num THEN RETURN NULL; END get_bfilename; /

dir_alias là tên thư mục cơ sở đữ liệu ảọ 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ử đụng file Raiders3.png, bạn có thể gọi hàm độc lập thông qua một query:

SELEGT get_bfilanamắITEM','ITEM_PHOT0','ITEM_ID','1055') AS directory

FROM dual;

Nó sẽ trả về:

DIRECTORY

/images/Raiders3.png

Chương trình QueryRelativeBFILẸphp sử dụng giá trị trả về

get_bñlename làm phần tử src của thể img Điều này chỉ làm việc khi bí

Trang 36

38 Chương 8: Các đối tượng lớn

PHP gọi đến hàm get_bfilename va trả về giá trị dưới dạng phần tử thứ ba trong querỵ 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 đữ liệụ

Sau đây là QueryRelativeBFILẸphp:

This is found in QueryRelativeBFILẸphp on the pubtisher’s web sitẹ <?php

// Declare input variables

(isset($_GET['id'}}) ? $id = (int) $_GET[{‘id’] : $id = 1021;

// Call the local function query_insert($id); /f Query results after an insert function query_insert($id) { // Return successful attempt to connect to the databas if ($Â = đ@oci_connect(plsql,"plsql,"orel")) { // Declare a SQL SELECT statement returning a CLOB $stmt = “SELECT item_title , item_dese get_bfilename(‘ITEM’ ,"ITEM_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

Trang 37

Chương 8: Các đối tượng lớn 39 $dafa = “â&nbsp;”; } else { if (oci_field_is_null($s,$i)) $title = “&nbsp;”; else if (Substr(oci_result($s,$i),0,1) == '/') $photo = oci_result($s,$i); else

$title = oci_result($s, $i); }

} / End of the while(oci_fetch($s)) loop

/{ Free statement resources oci_free_statement($s);

// Format HTML table to display BLOB photo and CLOB description Sout = ‘<table border="1° cellpađing="5" cellspacing="0">'; $out = ‘<tr>’; $out = ‘<td align="center” class="e">' $titlẹ'</td>'; $out = '</tr>'; $out = ‘<tr><td class="v">’; $out = ‘<div>';

$out = ‘<div style="margin-right:5px;float:left">';

Trang 38

40 Chương 8: Các đối tượng lớn Trong khi QueryRelativeBFILẸ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 đốị 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 file ảnh và phục vụ nó cho

server Apachẹ 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 ảọ 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 fđ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àỵ

Bục các tên fiiững tiấn và tên File chuẩn tắc

Phan nay minh họa cách bạn có thể chỉnh sửa catalog cơ sở dữ 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 file chuẩn tắc Bạn phải mở các quyển (permis-

sions) dé bdo vệ an toàn thư mục ảo được sở hữu bởi người dùng SY8 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ệụ Đ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ủ tục lưu trữ (và cũng đừng quên bao bọc nguồn khỏi những cặp mắt tò

mò) >

Trang 39

Chươ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_ directorles 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_ đirectorles Các đặc quyền vai trò không cho phép một người dùng xây dự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 khong thể truy cập khung xem đba_ directories thông qua vai

trò SELECT_CATALOG_ROLẸ

Bạn cần kết nối dưới dạng người dùng SY§ có đặc quyền như sau:

sqlplus ' / as sysdbá

Điều này sẽ đòi hỏi password quản trị cơ sở đữ liệụ 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 cu 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.sqi on the publisher's web sitẹ CREATE OR REPLACE FUNCTION get_directory_path

( virtual_directory IN VARCHAR2 ) RETURN VARCHARZ2 IS

Define return variablẹ

directory_ path VARCHAR2(256) := 'G:\’;

Define dynamic cursor

CURSOR get_directory (virtual_directory VARCHAR2) |S

SELECT directory_path FROM sys.dba_directories

WHERE directory_name = virtual_directory;

Trang 40

42 CLOSE get_directory; Return filenamẹ RETURN directory_path; EXCEPTION WHEN directory_name THEN RETURN NULL; END get_directory_path; /

Chương 8: Các đối tượng lớn

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ử dụ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 ảọ Nó trả về đường dẫn chuẩn tắc và tên file cơ sở cho bất kỳ

locator BFILẸ

get_canonical_bfilename su dung NDS (Native Dynamic SQL) dé tra

về một cột BFILẸ 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 BFILE 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 dịch

ham get_canonical_bfilename trong schema SYSTEM sau khi ban da

bién dich ham get_directory_path

Ngày đăng: 24/11/2013, 14:31

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w