Giới thiệu hệ quản trị cơ sở dữ liệu hướng đối tượng Oracle
Oracle là một trong số các hệ quản trị cơ sở dữ liệu quan hệ ra đời vào thập niên 70 và đến ngày nay nó trở thành một trong những hệ quản trị cơ sở dữ liệu dẫn đầu trong “làng” cơ sở dữ liệu trên thế giới như IBM DB2, Informix, SQL Server…
Vào năm 1977, Larry Ellison, Bod Miner và Ed Otaes thành lập một công ty và đặt tên là Relational Software Incorporation (RSI). Công ty này xây dựng một hệ quản trị cơ sở dữ liệu gọi là Oracle. Larry Ellison, Bod Miner và Ed Otaes quyết định phát triển hệ này bằng ngôn ngữ C và giao tiếp SQL.
Năm 1979, RSI phân phối sản phẩm đầu tiên cho khách hàng là hệ quản trị cơ sở dữ liệu Oracle phiên bản 2. Năm 1983, phiên bản 3 được giới thiệu với những thay đổi trong ngôn ngữ SQL, mở rộng hiệu suất và các cải tiến khác. Không như các phiên bản trước đây, phiên bản 3 hầu như được viết toàn bộ bằng ngôn ngữ C.
Đến năm 1984 phiên bản 4 được ra đời, đây được xem là phiên bản hợp nhất tính nhất quán trong đọc dữ liệu.
Phiên bản 5 được giới thiệu vào năm 1985 là một mốc lịch sử vì nó đã đưa công nghệ khách chủ vào thị trường với việc sử dụng SQL*.net.
Năm 1988 Oracle đưa ra phiên bản 6, chạy được trên nhiều nền và hệ điều hành khác nhau.
Oracle 7 được phát hành vào năm 1992 bao gồm nhiều thay đổi về tiện ích nhập/ xuất. Oracle 7 là hệ quản trị cơ sở dữ liệu quan hệ đầy đủ chức năng nhất được sử dụng trong nhiều năm. Nó có nhiều ưu điểm nhờ tính năng dễ sử dụng, công cụ SQL* DBA và các tiện ích khác.
Năm 1997, Oracle 8 giới thiệu thêm phần mở rộng đối tượng (Object Extension) cũng như tính năng và công cụ quản trị mới. Gần đây, Oracle 8.1.5 với tên gọi Oracle 8.i, phiên bản hỗ trợ nhiều tính năng mới và đặc biệt là các ứng dụng cơ sở dữ liệu Internet. Phiên bản Oracle 8.0 được cải tiến nhiều trong lĩnh vực quản trị dữ liệu. Mặc dù sự cải tiến Oracle 8i nhằm hỗ trợ cho sự phát triển Java. Oracle 8.i đã hoàn chỉnh trong việc quản trị dữ liệu đối tượng mà phiên bản 8.0 đã khởi xướng.
Từ phiên bản Oracle 8i đến nay đã hoàn thiện hơn với sự xuất hiện của Oracle 9i, 10g hỗ trợ các chức năng quản trị và xây dựng cơ sở dữ liệu hướng đối tượng
Kiểu dữ liệu hướng đối tượng
Phần này trình bày các kiểu dữ liệu hướng đối tượng cung cấp bởi Oracle và ngôn ngữ định nghĩa đối tượng ODL (Object Definied Language), ngôn ngữ truy vấn đối tượng OQL (Object Query Language)
Đối tượng là kiểu dữ liệu rất mạnh có trong phiên bản Oracle 8.i trở đi. Đối tượng đưa ra khả năng đóng gói dữ liệu, che dấu thông tin, thiết lập các thuộc tính, hành vi ứng xử cho đối tượng. Với Oracle, bạn có thể xây dựng các đối tượng thật sự mô phỏng các thực thể của thế giới mà chúng ta đang sống. Đối tượng mang tính trừu tượng hoá cao. Cấu trúc dữ liệu và mã lệnh được kết hợp với nhau để tạo nên một tổng thể duy nhất là đối tượng. Sử dụng đối tượng trong thiết kế cơ sở dữ liệu là yêu cầu của các ứng dụng đa dạng hiện nay. Bạn có thể dễ dàng lưu chúng vào một bảng, chèn thêm, xoá, sửa hay truy vấn đối tượng như các lệnh SQL thông thường. Thế giới quanh ta là một tập hợp đa dạng của nhiều đối tượng, Oracle và các công cụ phần mềm khác cũng không phải ngoại lệ. Oracle 8.i là một hệ quản trị cơ sở dữ liệu hướng đối tượng, nó trải qua nhiều năm từ hệ thống quan hệ thuần tuý truyền thống thành một hệ thống mở rộng các tính năng hướng đối tượng.
Trong Oracle có một ngôn ngữ đặc biệt, hoàn thiện cho phép kết hợp ngôn ngữ thủ tục truyền thống với truy xuất các đối tượng cơ sở dữ liệu thông qua SQL là PL/ SQL. Lập trình hướng đối tượng thực hiện dựa trên cơ sở các kiểu đối tượng (Object Type)
a. Các kiểu dữ liệu phức hợp định nghĩa sẵn
- Đối tượng lớn nhị phân lưu trong cơ sở dữ liệu (Binary Large Object - BLOB)
Kiểu dữ liệu BLOB là đối tượng lớn nhị phân lưu trữ dữ liệu nhị phân không có cấu trúc trong cơ sở dữ liệu, có thể lưu trữ tối đa bốn GB (Gigabyte) dữ liệu nhị phân.
- Đối tượng lớn ký tự lưu trong cơ sở dữ liệu (Character Large Object - CLOB)
Kiểu dữ liệu CLOB là đối tượng lớn ký tự lưu trữ tối đa bốn GB ký tự trong cơ sở dữ liệu.
- Đối tượng lớn ký tự chiều dài cố định (Fixed - Width Multibyte Character Large Object - NCLOB)
Kiểu dữ liệu NCLOB là đối tượng lớn ký tự chiều dài cố định lưu trữ tối đa bốn GB ký tự trong cơ sở dữ liệu. Các NCLOB lưu trữ dữ liệu có chiều dài dữ liệu cố định.
- Đối tượng lớn nhị phân lưu ngoài cơ sở dữ liệu (Binary Large File Object - BFile)
Kiểu dữ liệu BFILE là đối tượng lớn nhị phân lưu trữ dữ liệu nhị phân không có cấu trúc trong các tập tin của hệ điều hành ngoài cơ sở dữ liệu. Cột BFILE hoặc thuộc tính lưu trữ một bộ định vị tập tin chỉ đến tập tin bên ngoài chứa dữ liệu. Các BFILE có thể lưu trữ tối đa bốn GB dữ liệu. Các BFILE là chỉ đọc, bạn không thể sửa đổi chúng. Chúng chỉ hỗ trợ đọc ngẫu nhiên và chúng không tham gia vào các giao dịch.
b. Kiểu đối tượng (Object Type)
Khác với những dữ liệu tĩnh thông thường, một kiểu đối tượng sẽ biết cách tác động lên chính dữ liệu mà nó thể hiện thông qua các phương thức được xây dựng bên trong đối tượng. Để đưa một đối tượng vào dùng bạn chỉ cần biết chúng làm được những gì không cần phải biết chúng được cài đặt như thế nào.
Các kiểu đối tượng là các khái niệm trừu tượng hoá của các đối tượng trong thế giới khách quan. Một kiểu đối tượng là khuôn mẫu của đối tượng. Đơn vị dữ liệu có cấu trúc so khớp khuôn mẫu được gọi là đối tượng. Đối tượng là thể hiện của kiểu đối tượng
- Cấu trúc
Cấu trúc của một kiểu đối tượng bao gồm hai phần: phần đặc tả (Specification) và phần thân (Body) hay còn gọi là phần cài đặt. Phần đặc tả bao gồm các giao tiếp của đối tượng cung cấp cho chương trình ứng dụng, những giao tiếp này bao gồm cấu trúc dữ liệu thể hiện thuộc tính (Attribute) của đối tượng cùng với các phương thức (Method) được dùng để xử lý dữ liệu. Phần thân là nơi cài đặt chi tiết các phương thức trong phần đặc tả và thường được xem như một “hộp đen” (Black-Box) tách biệt đối với người sử dụng.
Ví dụ: Tạo kiểu đối tượng trong Oracle
// Cú pháp tạo phần đặc tả cho kiểu đối tượng
CREAT [OR REPLACE] TYPE tên_kiểu IS/AS OBJECT (
Tên_thuộc_tính Kiểu_dữ_liệu,
MEMBER FUNCTION Tên_hàm(ds_tham_đối) RETURN Kiểu_dữ_liệu,
MEMBER PROCEDURE Tên_thủ_tục(ds_tham_đối),…
);
// Cú pháp tạo phần thân cho kiểu đối tượng
CREATE[OR REPLACE] TYPE BODY tên_kiểu IS/AS
MEMBERFUNCTION Tên_hàm(ds_tham_đối) RETURN Kiểu_dữ_liệu IS
BEGIN Thân_hàm
END;
MEMBER PROCEDURE Tên_thủ_tục(ds_tham_đối) IS
BEGIN Thân_thủ_tục
END;
END;
-Thuộc tính
Là các biến dữ liệu khai báo bên trong một kiểu đối tượng. Các thuộc tính lập mô hình cấu trúc và trạng thái của thực thể thế giới thực.
Thuộc tính được khai báo theo tên với một kiểu dữ liệu nhất định. Tên của thuộc tính phải là duy nhất và không được trùng với tên thuộc tính hay phương thức có trong đối tượng. Kiểu dữ liệu của thuộc tính có thể là kiểu định nghĩa sẵn hay kiểu người dùng định nghĩa, có thể là bất kỳ kiểu dữ liệu mà bản thân Oracle hỗ trợ ngoại trừ các kiểu dữ liệu sau: LONG, LONG RAW, NCHAR, NCLOB, NVARCHAR2, ROWID, các kiểu dữ liệu đặc biệt của PL/SQL như BINARY-INTEGER, RECORD, REF CURSOR, %TYPE và ROWTYPE.
Kiểu dữ liệu của thuộc tính có thể là:
- Kiểu dữ liệu vô hướng định nghĩa sẵn như CHAR, NUMBER, VARCHAR, VARCHAR2, DATE…
- Kiểu đối tượng khác (Nested Object Type)
- Kiểu nhóm (Collection Type): Varray hay bảng lồng (Nested Table)
- Kiểu tham chiếu Ref
Bạn không thể khởi tạo giá trị ban đầu cho thuộc tính trong phần khai báo bằng toán tử gán hay mệnh đề DEFAULT cũng như đặt từ khoá ràng buộc NOT NULL cho thuộc tính. Tuy nhiên, kiểu đối tượng sau khi lưu vào CSDL nếu được dùng để khai báo kiểu cho một cột nào đó trong bảng thì bạn vẫn có thể áp dụng tính chất ràng buộc (NOT NULL) của bảng cho cột dữ liệu mang trị kiểu đối tượng.
Kiểu dữ liệu của thuộc tính phụ thuộc vào thuộc tính của đối tượng trong thế giới thực mà bạn muốn mô phỏng.
Cấu trúc dữ liệu của đối tượng có thể rất phức tạp. Ví dụ như kiểu dữ liệu của thuộc tính bản thân nó lại là một kiểu đối tượng khác. Cơ chế này cho phép bạn tạo ra những kiểu dữ liệu đối tượng đa dạng từ những thành phần đối tượng đơn giản khác.
- Phương thức
Phương thức là các hàm và thủ tục dùng cho việc xử lý dữ liệu và thể hiện bằng các hành vi của đối tượng tùy theo tình huống. Phương thức có thể được viết bằng PL/SQL và lưu trữ trong CSDL, hay được cài đặt bằng ngôn ngữ lập trình hướng đối tượng. Các phương thức bổ sung các hoạt động mà ứng dụng có thể thực hiện trên thực thể thế giới thực. Phương thức không được có tên trùng với tên đối tượng hay tên các thuộc tính đã khai báo trước. Các phương thức bên trong một kiểu đối tượng được chia làm hai phần: phần đặc tả bao gồm các khai báo về phương thức, các tham đối cần truyền cho phương thức, kiểu dữ liệu trả về cộng với từ khoá MEMBER cho biết phương thức khai báo được truy xuất từ bên ngoài đối tượng, phần thân là nơi thật sự cài đặt mã lệnh cho đối tượng. Những phương thức được khai báo trong phần đặc tả của đối tượng đều phải có sự cài đặt tương ứng cho phần thân. Trình biên dịch PL/SQL sẽ dò tìm các phương thức ở phần đặc tả và phần thân theo từng chuỗi ký tự tương ứng vì vậy phải khai báo các phương thức ở phần đặc tả và phần thân khớp với nhau theo từng từ một. Các thuộc tính hay phương thức bên trong đối tượng có thể tự do tham chiếu lẫn nhau mà không cần dùng thêm từ khoá nào khác.
Phương thức định nghĩa cho đối tượng có thể là:
§ Hàm (Function) và thủ tục (Procedure)
§ Phương thức ánh xạ (Map Method) và phân ngôi (Order Method)
§ Phương thức khởi tạo (Constructor Method)
Tất cả các phương thức trong đối tượng đều ngầm định tham đối đầu tiên truyền cho phương thức là con trỏ đến chính bản thân đối tượng. Con trỏ này được biết đến với tên nội tại được qui định sẵn là SFLF, mặc dầu bạn có khai báo tường minh hay không tường minh.
Ví dụ:
CREATE OR REPLACE TYPE TaiKhoan AS OBJECT (
soTK NUMBER,
pin NUMBER,
soTien NUMBER,
MEMBER FUNCTION moTK (SELF IN OUT TaiKhoan, soTien IN
NUMBER) RETURN TaiKhoan
);
CREATE TABLE Taikhoan_T OF TaiKhoan
CREATE OR REPLACE TYPE BODY TaiKhoan as
MEMBER FUNCTION moTK (SELF IN OUT TaiKhoan, soTien IN
NUMBER) RETURN TaiKhoan AS
BEGIN
IF soTien < 0 THEN
DBMS_OUTPUT.PUT_LINE('Không có tiền');
RETURN TaiKhoan(0,0,0);
END IF;
END;
Trong đối tượng nếu một hàm không khai báo tham đối đầu tiên là SELF thì ngầm định SELF được khai báo là tham đối mang thuộc tính IN, với một thủ tục nếu SELF không được khai báo thì mặc định Oracle sẽ khai báo SELF như là tham đối đầu tiên với thuộc tính IN OUT cho phương thức. SELF mang ý nghĩa là con trỏ đến chính thể hiện của bản thân kiểu đối tượng. Bạn có thể dùng SELF để tham chiếu đến mọi thuộc tính cũng như phương thức khai báo bên trong kiểu đối tượng.
Các phương thức trong đối tượng có khả năng nạp chồng (Overloading). Bạn có thể dùng cùng một tên gọi cho nhiều phương thức khác nhau nếu như các tham đối hình thức truyền cho phương thức có sự khác nhau về thứ tự, kiểu dữ liệu... Khi bạn gọi một phương thức bên trong đối tượng, PL/SQL phải tìm và so sánh danh sách các tham đối truyền cho phương thức để chọn đúng phương thức mà bạn cần gọi. Bạn có thể nạp chồng hai hàm có cùng tham đối nhưng chỉ khác nhau kiểu dữ liệu trả về.
Phương thức ánh xạ (Map Method) và phân ngôi (Order Method)
Như chúng ta đã biết, các giá trị của những kiểu dữ liệu vô hướng như CHAR, REAL, INTEGER đều có thể so sánh được với nhau, riêng kiểu dữ liệu đối tượng không thể đem so sánh với nhau một cách bình thường như các kiểu vô hướng. Để dễ so sánh với nhau bằng các phép toán >, <, = hay các mệnh đề sắp xếp thứ tự như distinct, group by, order by, PL/SQL cho phép cài đặt các phương thức được tự động gọi khi so sánh là :
- Phương thức ánh xạ
- Phương thức phân ngôi
Mỗi đối tượng chỉ có thể chứa một phương thức ánh xạ hoặc phân ngôi. Phương thức phân ngôi so sánh từng giá trị của đối tượng với nhau để quyết định sự lớn hơn, nhỏ hơn hay bằng nên thực hiện chậm hơn phương thức ánh xạ.
Phương thức ánh xạ dùng để chuyển đổi một đối tượng kiểu đối tượng sang trị vô hướng như REAL, DATE, NUMBER, VARCHARR2, CHAR, INTEGER… để dễ so sánh với các từ khoá khác. Mỗi kiểu đối tượng chỉ có thể chứa một phương thức ánh xạ và bắt đầu bằng từ khóa MAP. Mỗi phương thức ánh xạ chỉ có thể trả về một trong các kiểu dữ liệu sau: DATE, NUMBER, VARCHAR2, CHARACTER hay REAL.
Ví dụ :
# Định nghĩa kiểu đối tượng GioPhut
CREATE TYPE GioPhut AS OBJECT (
gio NUMBER,
phut NUMBER,
MAP MEMBER FUNCTION soPhut RETURN NUMBER,
MEMBER FUNCTION chuoiGio RETURN VARCHAR2);
CREATE TYPE BODY GioPhut AS
MAP MEMBER FUNCTION soPhut RETURN NUMBER IS
BEGIN RETURN gio*60 + phut;
END soPhut;
MEMBER FUNCTION chuoiGio RETURN VARCHAR2 IS
BEGIN RETURN lpad(gio,2,’0’) || ‘:’ || lpad(phut,2,’0’);
END chuoiGio;
END;
# Định nghĩa kiểu đối tượng DonHang
CREATE ORREPLACETYPE DonHang AS OBJECT (
maDH NUMBER,
ngayMua DATE,
ngayGiao DATE,
MAP MEMBER FUNCTION giamGia RETURN NUMBER);
CREATE or REPLACE TYPE BODY DonHang as
MAP MEMBER FUNCTION giamGia RETURN NUMBER IS
BEGIN RETURN 5/100;
END giamGia;
END;
Ngoài việc sử dụng phương thức ánh xạ, PL/SQL còn cung cấp cho bạn cách so sánh đối tượng dựa trên việc cài đặt các phương thức phân ngôi (Order Method) cho đối tượng. Một phương thức phân ngôi bắt đầu bằng từ khoá ORDER và trả về một trị số cho biết kết quả so sánh giữa hai đối tượng có cùng kiểu. Tương tự các phương thức ánh xạ, một kiểu đối tượng chỉ có thể cài đặt một phương thức phân ngôi. Phương thức phân ngôi có hai tham đối, tham đối thứ nhất là con trỏ self đến chính nó (có thể khai báo tường minh hay ngầm định), tham đối thứ hai là đối tượng có cùng kiểu muốn đem so sánh.
Ví dụ : # Phương thức phân ngôi
CREATE TYPE GioPhut AS OBJECT (
gio NUMBER,
phut NUMBER,
ORDER MEMBER FUNCTION soPhut(gp GioPhut) RETURN NUMBER);
CREATE TYPE BODY GioPhut AS
ORDER MEMBER FUNCTION soPhut(gp GioPhut) RETURN NUMBER IS
BEGIN
IF gio*60 + phut < gp.gio*60 + gp.phut THEN
RETURN -1;
ELSIF gio*60 + phut > gp.gio*60 + gp.phut THEN
RETURN 1;
ELSE RETURN 0;
END IF;
END;
END;
Các phương thức ánh xạ có tác dụng ánh xạ giá trị của đối tượng vào một giá trị vô hướng sau đó so sánh các đối tượng dựa trên các trị số vô hướng tương ứng. Còn các phương thức phân ngôi thì lại so sánh từng giá trị đặc trưng của các đối tượng với nhau để quyết định sự lớn hơn, nhỏ hơn hay bằng nên thường chậm hơn các phương thức so sánh theo kiểu ánh xạ. Nhưng khi sắp xếp hay thực hiện các thao tác tính toán trên một tập hợp lớn bao gồm nhiều đối tượng bạn nên cài đặt việc so sánh đối tượng theo phương pháp ánh xạ. Phương pháp này đổi tất cả các đối tượng ra trị vô hướng và chỉ thực hiện sắp xếp đối tượng một lần duy nhất cho tất cả các đối tượng.
Phương thức khởi tạo (Constructor Method)
Ngoài ra, với những kiểu đối tượng đều bao hàm mặc định một phương thức khởi tạo gọi là Constructor. Phương thức này đặc biệt có cùng tên với kiểu đối tượng và được hệ thống gọi đến khi đối tượng được hình thành trong bộ nhớ. Phương thức khởi tạo để gán trị mặc định cho thuộc tính, gọi các phương thức cần thiết. .
Như vậy, xây dựng kiểu đối tượng sẽ làm giảm độ phức tạp cho chương trình bằng cách chia một hệ thống lớn thành những thực thể logic nhỏ bạn có thể dễ quản lý và thiết kế chương trình hơn. Đối tượng cho phép bạn xây dựng được các phần mềm có khả năng bảo trì và sử dụng lại mã lệnh đạt độ tin cậy cao. Hơn nữa, lập trình theo mô hình đối tượng có thể giúp chương trình phát triển theo nhóm, mỗi nhóm sẽ xây dựng những đối tượng độc lập để ráp lại thành một tổng thể phần mềm duy nhất mà không cần phụ thuộc lẫn nhau.
c. Tạo bảng đối tượng
Một bảng đối tượng là một kiểu bảng đặc biệt lưu giữ các đối tượng. Để tạo bảng đối tượng ta dùng CREATE TABLE. Ta có thể dễ dàng chèn thêm, cập nhật, xóa hay truy vấn đối tượng bằng câu lệnh SQL như: INSERT, UPDATE, DELETE, SELECT... Bảng đối tượng có thể có dạng:
- Bảng dữ liệu mà có các cột có kiểu Object
- Bảng dữ liệu từ một kiểu Object. Các cột của bảng gồm các thuộc tính của đối tượng, các dòng của bảng xem như là một đối tượng.
Làm việc với kiểu Object mạnh hơn nhiều so với kiểu dữ liệu thông thường. Dữ liệu được lưu trong bảng không đơn thuần chỉ là những cột hay dòng dữ liệu tĩnh, mà là một đối tượng biết cách ứng xử và thể hiện dữ liệu do chúng bao bọc.
Ví dụ:
// Tạo bảng đối tượng KhachHang
CREATE OR REPLACE TYPE KhachHang AS OBJECT (
tenDangNhap VARCHAR2(10),
matKhau VARCHAR2(10),
hoTen VARCHAR2(30),
email VARCHAR2(50));
// Tạo bảng KhachHang_T
CREATE TABLE KhachHang_T OF KhachHang
//Hiển thị các khách hàng có trong bảng KhachHang_T
SELECT * FROM KhachHang_T
//Chèn khách hàng vào bảng KhachHang_T
INSERT INTO KhachHang_T
values(‘hoa’,’hoa’,’Nguyễn Thị Hoa’,‘hoa2006@yahoo.com’);
//Xóa khách hàng trong bảng KhachHang_T
DELETE FROM KhachHang_T WHERE tenDangNhap = ‘hoa’;
//Sửa thông tin khách hàng trong bảng KhachHang_T
UPDATE KhachHang_T SET email = ‘hoant@yahoo.com’ WHERE
tenDangNhap = ‘hoa’;
d. Bảng lồng (Nested table)
Bảng lồng nhau là một tập hợp những phần tử dữ liệu không có thứ tự, có cùng kiểu dữ liệu.
Định nghĩa kiểu bảng lồng không phân bổ không gian. Nó xác định kiểu dữ liệu mà bạn có thể sử dụng làm:
ü Kiểu dữ liệu cột của bảng quan hệ.
ü Thuộc tính của kiểu đối tượng
ü Biến, tham đối PL/SQL hoặc hàm trả về kiểu
Với bảng lồng, các thành phần thực sự lưu trữ trong bảng riêng (bảng lồng). Nếu kiểu thành phần là kiểu định nghĩa sẵn, bảng lồng có một cột với kiểu này, hay nếu kiểu thành phần là kiểu đối tượng, bảng có thể xem như là bảng nhiều cột, mỗi cột cho mỗi thuộc tính của kiểu đối tượng. Bảng lồng chứa thêm một cột định nghĩa hàng bảng cha hay đối tượng mà mỗi thành phần thuộc về.
Có thể sử dụng bảng lồng định nghĩa cho một thuộc tính của kiểu đối tượng
Các kiểu nhóm - gồm các thành phần có cùng kiểu - hỗ trợ trong Oracle là Varray, bảng lồng. Oracle mô hình hoá kiểu nhóm như là quan hệ tụ hợp, hợp thành, thuộc tính đa trị trong đối tượng phức hợp
Ví dụ:
// Định nghĩa quan hệ tụ hợp giữa kiểu đối tượng DonHang và DonHangCT sử dụng bảng // lồng
CREATE OR REPLACE TYPE DonHangCT AS OBJECT (
soLuong NUMBER,
maHangRef ref MatHang);
CREATE TYPE DonHangCT_T AS TABLE OF DonHangCT;
CREATE OR REPLACE TYPE DonHang AS OBJECT (
maDH NUMBER,
ngayMua DATE,
ngayGiao DATE,
tenDangNhapRef ref KhachHang,
dHCT DonHangCT_T);
CREATE TABLE DonHang_T OF DonHang NESTED TABLE dHCT STORE AS
DSDHCT;
// Thêm dữ liệu, cập nhật dữ liệu và xoá dữ liệu từ bảng DonHang_T
INSERT INTO DonHang_T VALUES
(1,sysdate, to_date(‘9/6/2005’,’dd/mm/yyyy’), null, DonHangCT_T
(DonHangCT (1,null),DonHangCT(3,null)));
UPDATE DonHang_T SET
tenDangNhapRef = (SELECT REF(k) FROM KhachHang_T k WHERE
k.hoTen = ‘Nguyen Thi Thu’ );
UPDATE TABLE (SELECT dHCT FROM DonHang_T WHERE maDH=1) SET maHangRef = (SELECT ref(h) FROM MatHang_T m where m.maHang=1);
DELETE FROM DonHang_T where maDH = 1;
e. Kiểu mảng (Varray Type)
Mảng là một tập hợp có thứ tự của những phần tử dữ liệu. Tất cả những phần tử của một mảng thuộc cùng kiểu dữ liệu. Mỗi phần tử có một chỉ mục là số tương ứng với vị trí của phần tử trong mảng. Số phần tử trong một mảng là kích thước của mảng. Oracle cho phép các mảng có kích thước khả biến, đó là lý do tại sao chúng được gọi là VARRAY.
Tạo một kiểu mảng không phân bổ không gian. Nó xác định kiểu dữ liệu mà bạn có thể sử dụng làm:
- Kiểu dữ liệu cột của một bảng quan hệ
- Một thuộc tính kiểu đối tượng
- Biến, tham đối PL/SQL hoặc hàm trả về kiểu
Ví dụ:
//Định nghĩa mảng DienThoai kiểu VARRAY
CREATE OR REPLACE TYPE DienThoai AS VARRAY(3) OF VARCHAR2(20);
Kiểu mảng DienThoai có số phần tử không nhiều hơn 3, có kiểu dữ liệu phần tử là varchar2(20).
Ví dụ:
// Định nghĩa kiểu đối tượng KhachHang, DiaChi
// Quan hệ hợp thành giữa kiểu đối tượng KhachHang và kiểu đối tượng DiaChi
// Quan hệ hợp thành giữa kiểu đối tượng KhachHang và kiểu VARRAY DienThoai
CREATE OR REPLACE TYPE DiaChi AS OBJECT (
soNha VARCHAR2(15),
duong VARCHAR2(25),
thanhPho VARCHAR2(25),
quocGia VARCHAR2(25));
CREATE OR REPLACE TYPE KhachHang AS OBJECT (
tenDangNhap VARCHAR2(10),
matKhau VARCHAR2(10),
hoTen VARCHAR2(30),
diaChis DiaChi,
dienThoais DienThoai,
email VARCHAR2(50));
CREATE TABLE KhachHang_T OF KhachHang;
// Chèn dữ liệu vào bảng KhachHang_T
INSERT INTO KhachHang_T VALUES (
‘hoa’, ’hoa’, ’Nguyen Thi Hoa’, DiaChi(‘202’,’Le Loi’,’Da nang’,
’Viet Nam’), DienThoai(‘750666’, ‘123456’), null);
// Truy vấn dữ liệu từ bảng KhachHang_T
SELECT hoTen, k.diaChis.soNha, k.diaChis.duong,
k.diaChis.thanhPho, k.diaChis.quocGia, dt.*
FROM KhachHang_T k, table(k.dienThoais) dt WHEREtenDangNhap = ‘hoa’;
// Cập nhật dữ liệu từ bảng KhachHang_T
UPDATE KhachHang_T SET email = ‘hoaNT@yahoo.com’
WHERE tenDangNhap = ‘hoa’
// Xóa dữ liệu từ bảng KhachHang_T
DELETE FROM KhachHang_T where tenDangNhap = ’hoa’;
f. Kiểu tham chiếu Ref (Reference)
Trong mô hình quan hệ, ta đã sử dụng kỹ thuật tham chiếu dưới hình thức thiết lập các khóa ngoại để liên kết các bảng với nhau. Nhưng với mô hình đối tượng thì việc tham chiếu không cần đến các khóa, bạn chỉ cần cho biết một thuộc tính nào đó của đối tượng mang kiểu con trỏ (REF) tham chiếu đến một đối tượng khác. Thậm chí có thể xây dựng những kiểu Object mang tính đệ quy (Recursive Object) nghĩa là bản thân Object mang những thuộc tính có kiểu con trỏ trỏ đến chính nó.
Oracle mô hình hoá kiểu tham chiếu REF như là quan hệ kết hợp, quan hệ kế thừa. Cơ chế tham chiếu và dùng chung (Sharing) các đối tượng dưới hình thức con trỏ (By Ref) sẽ nhanh hơn nhiều so với cơ chế tham chiếu theo trị (By Value) như trong mô hình quan hệ.
- Với quan hệ kết hợp, trong kiểu đối tượng bên nhiều sẽ tạo thuộc tính kiểu tham chiếu đến kiểu đối tượng bên 1
- Với quan hệ kế thừa, trong kiểu đối tượng con, sẽ tạo thuộc tính kiểu tham chiếu đến kiểu đối tượng cha
Ví dụ 1:
// Định nghĩa kiểu đối tượng LoaiHang, MatHang
// Quan hệ kết hợp 1 nhiều 1 chiều giữa kiểu đối tượng LoaiHang và MatHang
CREATE OR REPLACE TYPE LoaiHang AS OBJECT (
maLoai NUMBER,
tenLoai VARCHAR2(25),
hinh VARCHAR2(50));
CREATE TABLE LoaiHang_T OF LoaiHang;
CREATE OR REPLACE TYPE MatHang AS OBJECT (
maHang NUMBER,
tenHang VARCHAR2(50),
moTa VACHAR2(2000),
hinh VARCHAR2(50),
donGia NUMBER,
giamGia NUMBER,
maLoaiRef ref Loaihang);
CREATE TABLE MatHang_T OF MatHang;
Truy xuất đối tượng được tham chiếu bằng một REF được gọi là giải tham chiếu. Oracle cung cấp toán tử DEREF để thưc hiện điều này.
// Truy vấn bảng MatHang_T
SELECT tenHang, moTa, DEREF(maLoaiRef).tenLoai
FROM MatHang_T WHERE DEREF(maLoaiRef).maLoai = 1;
// Chèn, cập nhật dữ liệu vào bảng MatHang_T
INSERT INTO MatHang_T VALUES(1, ‘Giường kiểu Hoa Cúc La Mã’,
‘Những bông hoa được chạm trổ rất đẹp’, ’hinh.jpg’, 450000, 0, null);
UPDATE MatHang_T SET maLoaiRef =
(SELECT REF(l) FROM LoaiHang_T l WHERE l.maLoai = 1)
WHERE maHang = 2;
// Xóa dữ liệu từ bảng MatHang_T
DELETE FROM MatHang_T WHERE maHang = 2;
Ví dụ 2:
// Quan hệ kế thừa giữa kiểu đối tượng VeChon kế thừa LoaiVe
CREATE OR REPLACE TYPE VeChon AS OBJECT (
veChonid NUMBER,
tangGia NUMBER,
loaiVeRef ref LoaiVe);
CREATE TABLE VeChon_T OF VeChon;
Khi đối tượng tham chiếu bị hủy bỏ thì thuộc tính tham chiếu đến đối tượng không có thực, trường hợp này là dangling. Ví dụ khi bạn xóa đi một loại hàng trong bảng LoaiHang_T thì các đối tượng tương ứng trong bảng MatHang_T đều trỏ đến một loại hàng không có thực, để tránh trường hợp này bạn có thể sử dụng lệnh UPDATE đặt các thuộc tính tham chiếu về null như sau:
UPDATE MatHang_T SET maLoaiRef = null
WHERE maLoaiRef is dangling;
Ngôn ngữ lập trình PL/SQL (Procedural Language/ Structured Query Language)
a. Giới thiệu PL/SQL
PL/SQL là một ngôn ngữ lập trình dùng để truy nhập vào CSDL Oracle từ nhiều môi trường khác nhau. PL/SQL được tích hợp trên Server CSDL cho nên nó có thể được thực hiện nhanh và hiệu quả. PL/SQL có nhiều ưu điểm so với các ngôn ngữ lập trình khác về mặt quản lý logic và hỗ trợ các quy luật hoạt động của các ứng dụng CSDL. Đó là một ngôn ngữ đặc biệt, hoàn thiện cho phép kết hợp ngôn ngữ thủ tục truyền thống với truy xuất các đối tượng CSDL thông qua SQL. Mă PL/SQL được sử dụng để giao tiếp với cơ sở dữ liệu được lưu trữ trực tiếp trong cơ sở dữ liệu Oracle, và là ngôn ngữ lập trình duy nhất giao tiếp với cơ sở dữ liệu Oracle một cách tự nhiên bên trong môi trường cơ sở dữ liệu. PL/SQL không thể hoàn thiện nếu không có sự tương tác dễ dàng với cơ sở dữ liệu Oracle. Bất kỳ xử lý hay thay đổi dữ liệu nào cũng được hoàn thành trong PL/SQL mà không cần thêm môi trường lập trình nào khác. Không có giao tiếp ODBC, cũng không cần nhúng bất cứ phép xử lý dữ liệu nào.
b. Các đặc điểm của PL/SQL
- Cấu trúc khối: đơn vị cơ bản của PL/SQL là một khối. Tất cả các chương trình của PL/SQL được xây dựng từ những khối. Mỗi khối là một đơn vị công việc logic trong một chương trình. Cấu trúc của một khối như sau:
DECLARE
/* Phần khai báo – các biến, kiểu, cursor và chương trình con nằm ở đây */
BEGIN
/* Phần thực hiện – các thủ tục và câu lệnh SQL nằm ở đây. Đây là phần
chính và yêu cầu phải có. */
EXCEPTION
/* Phần kiểm soát lỗi */
END;
- Biến và kiểu: PL/SQL hỗ trợ các biến và kiểu tương tự như ngôn ngữ lập trình khác. PL/SQL cũng cho phép sử dụng các kiểu dữ liệu người dùng định nghĩa như kiểu bảng (Table) và kiểu bản ghi (Record)
- Cấu trúc vòng lặp và rẽ nhánh: Cũng như ngôn ngữ lập trình bậc cao như Pascal, Visual Basic…PL/SQL cho phép sử dụng các cấu trúc điều khiển điều kiện và cấu trúc lặp
- Cursor: được dùng để thao tác với nhiều hàng dữ liệu lấy từ CSDL (dùng câu lệnh Select). Bằng cách sử dụng Cursor, chương trình có thể duyệt một cách dễ dàng toàn bộ các hàng dữ liệu. Để xử lý câu lệnh SQL, Oracle tạo ra một vùng nhớ gọi là vùng ngữ cảnh (Context Area). Vùng ngữ cảnh chứa những thông tin cần thiết để hoàn thành một quá trình, bao gồm số hàng được xử lý bởi câu lệnh, con trỏ tới câu lệnh. Trong trường hợp một Query, vùng ngữ cảnh là một tập hợp các hàng được trả về bởi Query đó. Cursor là một thẻ (Handle) hoặc một con trỏ (Pointer) trỏ tới vùng ngữ cảnh. Thông qua Cursor, một chương trình PL/SQL có thể điều khiển vùng ngữ cảnh, 4 bước cần thiết để xử lý Cursor:
§ Khai báo Cursor
§ Mở Cursor để thực hiện Query
§ Đưa kết quả vào biến PL/SQL
§ Đóng Cursor
c. Cấu trúc của PL/SQL
Có thể nói PL/SQL là ngôn ngữ cấu trúc khối (Block-Structure). Đơn vị cơ bản trong mỗi chương trình PL/SQL là khối. Tất cả các chương trình PL/SQL đều được hợp thành từ những khối. Các khối có thể tuần tự hoặc lồng nhau. Mỗi khối liên quan đến một vấn đề hoặc một vấn đề con cần được giải quyết. PL/QL hỗ trợ cách tiếp cận giải quyết vấn đề theo kiểu “chia để trị”.
Có một vài kiểu khối bao gồm:
- Khối không tên (Anonymous Block): thường được xây dựng tự động và được thực hiện duy nhất một lần.
- Khối có tên (Named Block): là những khối không tên với nhãn được gán cho tên của khối.
- Chương trình con (Subprogram): là những thủ tục (Procedure), gói (Package) và hàm (Function) được lưu trong cơ sở dữ liệu. Những khối này thường không thay đổi một khi đã được xây dựng và chúng được thực hiện nhiều lần. Thực hiện chương trình con bằng lời gọi thủ tục, gói hoặc hàm cần thực hiện.
- Trigger: tương tự như chương trình con, chúng cũng được lưu trong cơ sở dữ liệu và được thực hiện nhiều lần, đồng thời ít thay đổi sau khi tạo ra. Trigger được thực hiện mỗi khi có một sự kiện được kích hoạt.
Trong mỗi khối của chương trình, PL/SQL đều có những phần tách biệt nhau: phần khai báo, phần thực hiện và phần kiểm soát lỗi. Chỉ có phần thực hiện là bắt buộc phải có còn hai phần kia có thể có hoặc không.
Phần khai báo là nơi mà tất cả các biến, cursor và các kiểu dùng trong khối được khai báo. Những hàm và thủ tục địa phương cũng có thể được khai báo ở đây. Phần thực hiện là phần chính của khối, là nơi thực hiện công việc của khối. Phần này bao gồm các câu lệnh SQL và những câu lệnh gọi thủ tục. Lỗi được kiểm soát trong phần kiểm soát lỗi. Mã chương trình này chỉ được thực hiện khi có lỗi xảy ra. Trong PL/SQL có 2 loại lỗi chính là: Compile (lỗi phát sinh khi dịch) và Run-time (lỗi phát sinh khi chạy). PL/SQL kiểm soát lỗi thông qua ngoại lệ (Exceptions) và xử lý ngoại lệ (Exception Handlers). Exception được thiết kế để xử lý những lỗi phát sinh khi chạy chương trình, còn đối với những lỗi phát sinh khi dịch sẽ được phát hiện bởi PL/SQL và trả về thông báo cho người sử dụng. Khi có lỗi phát sinh, một ngoại lệ được phát sinh, quyền điều khiển được chuyển sang phần kiểm soát lỗi. Nhờ việc thiết kế phần mềm kiểm soát lỗi một cách độc lập nên tính logic của chương trình dễ hiểu hơn, đồng thời nó cũng bảo đảm tất cả mọi lỗi sẽ được kiểm soát. Những từ khoá DECLARE, BEGIN, EXCEPTION và END ngăn cách những khối với nhau.
Ví dụ:
// Tạo bảng SinhVien
CREATE OR REPLACE TYPE SinhVien AS OBJECT (
maSV NUMBER,
tenSV VARCHAR2(20),
ngaySinh DATE,
);
CREATE TABLE SinhVien_T OF SinhVien;
// Xây dựng khối PL/SQL
DECLARE
// Bắt đầu phần khai báo
maSVs NUMBER(5) := 10;
tenSVs VACHAR2(20);
BEGIN
// Bắt đầu phần thực hiện
// Tìm tên của sinh viên có maSV = 10
SELECT tenSV INTO tenSVs FROM SinhVien_T WHERE maSV =
maSVs;
EXCEPTION
// Bắt đầu phần kiểm soát lỗi
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT('Sinh vien co ma so 10 khong ton tai');
END;
d. Hàm và thủ tục trong PL/SQL
Hàm và thủ tục trong PL/SQL rất giống hàm và thủ tục trong các ngôn ngữ lập trình cấp cao.
Thủ tục (Procedure)
Cú pháp để tạo một thủ tục:
CREATE OR REPLACE PROCEDURE Tên_thủ_tục
[(Tham_đối [IN | OUT | IN OUT] kiểu,
…
Tham_đối [IN | OUT | IN OUT] kiểu )] IS / AS
Thân_thủ_tục
Trong đó:
§ IN (tham trị): giá trị hiện tại của tham đối được truyền vào trong thủ tục khi thủ tục đó được gọi. Bên trong thủ tục, dạng của tham đối được xem là read-only, nghĩa là không thể được thay đổi. Khi kết thúc thủ tục, quyền điều khiển được trả về cho môi trường, giá trị của tham đối không đổi.
§ OUT (tham biến): mọi giá trị của tham đối khi bắt đầu lời gọi thủ tục đều bị bỏ qua. Trong thủ tục, dạng của tham đối được coi là write-only. Khi kết thúc thủ tục, nội dung của tham đối trong thủ tục được chuyển lại cho môi trường hiện tại.
§ IN OUT (vừa là tham biến vừa là tham trị): kiểu này kết hợp cả hai kiểu IN và OUT. Giá trị của tham đối hiện tại được chuyển vào trong thủ tục khi thủ tục được gọi. Bên trong thủ tục, tham đối này có thể được đọc và ghi. Khi kết thúc thủ tục, nội dung của tham đối trong thủ tục được chuyển lại cho môi trường hiện tại.
Hàm (Function)
Cú pháp để tạo hàm tương tự như cú pháp tạo thủ tục:
CREATE [OR REPLACE] FUNCTION Tên_hàm
[(Tham_đối [IN | OUT | IN OUT] kiểu,
…
Tham_đối [IN | OUT | IN OUT] kiểu )]
RETURN Kiểu_trả_về IS | AS
Thân_hàm
Bên trong thân hàm, câu lệnh Return được dùng để trả về một giá trị. Hàm có những tính chất tương tự như thủ tục:
§ Hàm có thể trả về nhiều hơn một giá trị thông qua tham đối OUT.
§ Mã lệnh của hàm cũng gồm 3 phần: khai báo, thực hiện và điều khiển lỗi.
§ Hàm có thể nhận giá trị mặc định.
Để xoá hàm và thủ tục ta dùng: DROP PROCEDURE Tên_thủ_tục
DROP FUNCTION Tên_hàm
TRUY CẬP CSDL HƯỚNG ĐỐI TƯỢNG ORACLE
Truy cập CSDL hướng đối tượng Oracle trong ASP
Kết nối và truy vấn cơ sở dữ liệu quan hệ - đối tượng Oracle
Tập tin global.asa
<OBJECT RUNAT=Server SCOPE=Application ID=OraSession PROGID="OracleInProcServer.XOraSession"></OBJECT>
<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
Sub Application_OnStart
OraSession.CreateDatabasePool 20, 100, 600, "muave", "thi/ntmt", 0
End Sub
Sub Application_OnEnd
OraSession.DestroyDatabasePool
End Sub
Sub Session_OnStart
End Sub
Sub Session_OnEnd
End Sub
</SCRIPT>
<% set OraDatabase = OraSession.getDatabaseFromPool(10)
set OraDynaset = OraDatabase.CreateDynaset("SELECT mahang, tenhang, mota, hinh, dongia, deref(maloairef).maloai from mathang_t”)
while not rs.eof
mahang = rs("mahang")
tenhang = rs("tenhang")
rs.MoveNext
wend
rs.close
OraDynaSet.close
%>
Truy cập CSDL hướng đối tượng Oracle trong Java - JSP
<%@ page import="java.sql.*,javax.sql.*,oracle.jdbc.driver.*,oracle.sql.*" %>
<%
DriverManager.registerDriver(new OracleDriver());
Connection con =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:csdl","bhang","bhang");
Statement stm = con.createStatement();
ResultSet rs = stm.executeQuery("SELECT mahang, tenhang, mota, hinh, dongia, deref(maloairef).maloai from mathang_t where deref(maloairef).maloai='01’”);
while (rs.next()){
String mahang = rs.getString("mahang");
String tenhang=rs.getString("tenhang");
}
con.close();
stm.close(); %>
» Tin mới nhất:
» Các tin khác: