Ràng buộc cơ sở dữ liệu trong Firebird và InterBase
LƯU Ý: Tài liệu này là chương trích từ cuốn sách “The InterBase World” được viết bởi Alexey Kovyazin và Serg Vostrikov.
Chương này dành cho các ràng buộc (constraints) của cơ sở dữ liệu InterBase và Firebird. Ràng buộc cơ sở dữ liệu là các quy tắc xác định mối quan hệ giữa các bảng và có thể kiểm tra cũng như sửa đổi dữ liệu trong cơ sở dữ liệu. Các quy tắc này được hiện thực hóa dưới dạng các đối tượng cơ sở dữ liệu đặc biệt. Ưu điểm chính của việc sử dụng ràng buộc nằm ở khả năng thực hiện kiểm tra dữ liệu và một phần logic nghiệp vụ của ứng dụng ở cấp độ cơ sở dữ liệu, tức là tập trung hóa và đơn giản hóa nó, từ đó làm cho việc phát triển các ứng dụng cơ sở dữ liệu dễ dàng và đáng tin cậy hơn.
Các nhà phát triển mới bắt đầu thường bỏ qua việc sử dụng các ràng buộc cơ sở dữ liệu, cho rằng chúng cản trở công việc sáng tạo. Tuy nhiên, thực tế quan điểm như vậy được hình thành do thiếu hiểu biết về lý thuyết và thực hành thiết kế cơ sở dữ liệu.
Đồng thời, các nhà thiết kế giàu kinh nghiệm nhất dám từ chối sử dụng một số loại ràng buộc, nhờ đó ứng dụng của họ thắng về tốc độ. Kinh nghiệm của các nhà thiết kế chuyên gia cho phép họ hiểu rất rõ hoạt động của máy chủ và dự đoán chính xác hành vi của nó trong các trường hợp phức tạp, do đó tốt hơn là các lập trình viên mới bắt đầu với InterBase không nên bắt chước những hành động tương tự của các đồng nghiệp giàu kinh nghiệm.
Trong cuốn sách này, chúng tôi không xem xét thiết kế cơ sở dữ liệu, vì vậy để biết thêm thông tin về vấn đề này, hãy xem danh sách tài liệu tham khảo ở cuối sách. Ở đây chúng tôi sẽ chỉ xem xét tất cả các loại ràng buộc trong cơ sở dữ liệu InterBase và xem xét các ví dụ về ứng dụng của chúng.
Các loại ràng buộc trong cơ sở dữ liệu
Có các loại ràng buộc sau trong cơ sở dữ liệu InterBase:
- PRIMARY KEY;
- UNIQUE KEY;
- FOREIGN KEY
- có thể bật các trigger tự động - ON UPDATE và ON DELETE;
- CHECK
Trong các chương trước, chúng tôi đã đề cập đến một số ràng buộc này, vì cần thiết cho việc trình bày logic của tài liệu, nhưng bây giờ chúng tôi sẽ xem xét chi tiết hơn về cú pháp, ứng dụng và cách triển khai của chúng. Ràng buộc cơ sở dữ liệu có hai loại - dựa trên một trường và dựa trên nhiều trường của bảng. Cú pháp của cả hai loại ràng buộc được đưa ra dưới đây.
= [CONSTRAINT constraint]
[ …]
= {UNIQUE | PRIMARY KEY
| CHECK ( )
| REFERENCES other_table [( other_col [, other_col …])]
[ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
[ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
}
Cú pháp của các ràng buộc dựa trên nhiều trường như sau:
= [CONSTRAINT constraint]
[< tconstraint> …]
= {{PRIMARY KEY | UNIQUE} ( col [, col …])
| FOREIGN KEY ( col [, col …]) REFERENCES other_table[( other_col [, other_col …])]
[ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
[ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
| CHECK ( )}
Sự khác biệt về cú pháp giữa các ràng buộc dựa trên một trường và dựa trên nhiều trường là rõ ràng - trong trường hợp sau, chúng ta có thể chỉ định một vài trường được đưa vào ràng buộc. Trong trường hợp ràng buộc dựa trên một trường, tất cả các tùy chọn được mô tả chỉ liên quan đến trường hiện tại. Chắc chắn, hai loại ràng buộc này có cách ứng dụng khác nhau: các ràng buộc dựa trên một trường chỉ đơn giản được thêm vào định nghĩa của trường cần thiết, còn các ràng buộc dựa trên nhiều trường được chỉ định sau dấu phẩy trong định nghĩa chung của bảng. Các ví dụ chi tiết được đưa ra trong các phần sau của chương này.
Ví dụ về ràng buộc điển hình
Thực tế, các ràng buộc dựa trên một trường là một trường hợp đặc biệt của các ràng buộc dựa trên nhiều trường.
Ví dụ về việc tạo ràng buộc khóa chính bằng hai cách tiếp cận khác nhau được đưa ra dưới đây. Hãy tạo một bảng chỉ chứa một trường và đặt ràng buộc khóa chính cho nó.
Đây là ví dụ về khóa chính sử dụng cú pháp ràng buộc dựa trên một trường:
CREATE TABLE test1( ID_PK INTEGER CONSTRAINT pktest NOT NULL PRIMARY KEY); Trong ví dụ này, một khóa chính có tên pktest được tạo cho trường ID_PK. Kết quả là chúng ta có một mô tả khá gọn gàng trong một dòng. Chúng ta có thể sử dụng cú pháp ràng buộc dựa trên nhiều trường cho cùng mục đích: CREATE TABLE test2( ID_PK INTEGER NOT NULL, CONSTRAINT pktst PRIMARY KEY (ID_PK));
Tạo ràng buộc
Hãy xem xét việc tạo ràng buộc chi tiết hơn. Đầu tiên trong mô tả cú pháp chung của ràng buộc là tùy chọn [CONSTRAINT constraint]. Như bạn có thể thấy, tùy chọn này được đặt trong dấu ngoặc vuông, tức là tùy chọn.
Sử dụng tùy chọn này, bạn có thể đặt tên cho ràng buộc được tạo cả trong trường hợp áp dụng cú pháp ràng buộc dựa trên một trường, cũng như trong trường hợp ràng buộc dựa trên nhiều trường. Nếu bạn không chỉ định tên cho ràng buộc, InterBase sẽ tự động tạo tên. Tuy nhiên, tốt hơn là đặt tên cho ràng buộc được tạo để cải thiện khả năng đọc của lược đồ cơ sở dữ liệu và đơn giản hóa việc quản lý ràng buộc sau này.
Sau khi đặt tên cho ràng buộc, loại của nó cần được xác định. Hãy xem xét các loại ràng buộc khác nhau theo thứ tự như chúng được chỉ ra trong mô tả cú pháp chung của ràng buộc.
Khóa chính và khóa duy nhất
Khóa chính là một trong những loại ràng buộc cơ sở dữ liệu chính. Chúng được áp dụng để xác định duy nhất các bản ghi trong bảng. Giả sử chúng ta lưu trữ danh sách người trong cơ sở dữ liệu. Rất có thể sẽ có hai (hoặc nhiều) người có cùng họ, tên và tên đệm. Làm thế nào chúng ta có thể phân biệt người này với người khác (chắc chắn, câu hỏi là phân biệt người này với người khác theo thông tin được lưu trữ trong cơ sở dữ liệu)?
Trong trường hợp này, “người” được đại diện bởi một bản ghi trong bảng, do đó chúng ta có thể đặt câu hỏi tổng quát hơn - làm thế nào chúng ta có thể phân biệt một bản ghi trong (bất kỳ) bảng với bản ghi khác trong cùng bảng. Vì mục đích này, các ràng buộc - khóa chính được sử dụng. Khóa chính đại diện cho một hoặc một vài trường trong bảng, sự kết hợp của chúng là duy nhất cho mỗi bản ghi. Không có giá trị lặp lại của khóa chính cho một bảng.
Khóa duy nhất thực hiện cùng chức năng - chúng cũng phục vụ cho việc xác định duy nhất các bản ghi trong bảng. Sự khác biệt giữa khóa chính và khóa duy nhất là chỉ có thể có một khóa chính trong bảng, còn khóa duy nhất - có thể có nhiều. Cần lưu ý rằng cả khóa chính và khóa duy nhất đều có thể được sử dụng làm cơ sở tham chiếu cho khóa ngoại (xem thêm phần sau).
Mô tả chính thức về các khái niệm khóa chính và khóa duy nhất, cũng như các định nghĩa quan trọng khác có thể được tìm thấy trong phụ lục “Bảng thuật ngữ” ở cuối sách. Cú pháp tạo khóa chính và khóa duy nhất dựa trên một trường duy nhất như sau:
< pkukconstraint > = [CONSTRAINT constraint] {PRIMARY KEY | UNIQUE}
Ví dụ về khóa chính và khóa duy nhất:
CREATE TABLE pkuk( pk NUMERIC(15,0) NOT NULL PRIMARY KEY, /*khóa chính*/
uk1 VARCHAR(50) NOT NULL UNIQUE,/*khóa duy nhất*/
uk2 INTEGER NOT NULL UNIQUE /\* thêm một khóa duy nhất nữa */);
Cú pháp tạo khóa chính và khóa duy nhất dựa trên nhiều trường:
= [CONSTRAINT constraint] {PRIMARY KEY | UNIQUE} ( col [, col …])
Cú pháp như vậy cho phép tạo khóa dựa trên sự kết hợp của các trường. Dưới đây là các ví dụ về việc tạo khóa chính và khóa duy nhất từ nhiều trường:
CREATE TABLE pkuk2( Number1 INTEGER NOT NULL, Name1 VARCHAR(50) NOT NULL, Kol INTEGER NOT NULL, Stoim NUMERIC(15,4) NOT NULL, CONSTRAINT pkt PRIMARY KEY (Number1, Name1), /*khóa chính pkt dựa trên hai trường*/ CONSTRAINT ukt1 UNIQUE (kol, Stoim)); /*khóa duy nhất ukt1 dựa trên hai trường*/
Lưu ý rằng tất cả các trường được đưa vào khóa chính và khóa duy nhất phải được khai báo là NOT NULL vì các khóa này không thể có giá trị không xác định. Ngoài việc tạo ràng buộc khóa chính và khóa duy nhất khi tạo bảng, có khả năng thêm ràng buộc vào bảng đã tồn tại. Trong trường hợp này, câu lệnh DDL: ALTER TABLE được sử dụng. Cú pháp thêm ràng buộc khóa chính hoặc khóa duy nhất vào bảng hiện có tương tự như mô tả ở trên:
ALTER TABLE tablename ADD [CONSTRAINT constraint] {PRIMARY KEY | UNIQUE} ( col [, col …])
Hãy xem xét ví dụ về việc tạo khóa chính và khóa duy nhất bằng ALTER TABLE:
CREATE TABLE pkalter( ID1 INTEGER NOT NULL, ID2 INTEGER NOT NULL, UID VARCHAR(24));
Sau đó chúng ta thêm khóa. Khóa chính trước:
ALTER TABLE pkalter ADD CONSTRAINT pkal1 PRIMARY KEY (id1, id2);
Sau đó khóa duy nhất: ALTER TABLE pkalter ADD CONSTRAINT ukal UNIQUE (uid);
Cần lưu ý rằng chỉ chủ sở hữu của bảng này hoặc quản trị viên hệ thống SYSDBA (để biết thêm chi tiết về chủ sở hữu và người dùng SYSDBA, xem chương “Bảo mật trong InterBase: người dùng, chức năng và quyền của họ” - phần 4) mới có thể thực hiện việc thêm (cũng như xóa) khóa chính và khóa duy nhất vào bảng.
Khóa ngoại
Ràng buộc tiếp theo thường được sử dụng trong cơ sở dữ liệu InterBase là ràng buộc khóa ngoại. Đây là một công cụ rất mạnh mẽ để cung cấp tính toàn vẹn tham chiếu trong cơ sở dữ liệu, cho phép không chỉ giám sát sự hiện diện của các tham chiếu chính xác trong cơ sở dữ liệu mà còn kiểm soát các tham chiếu này một cách tự động!
Ý nghĩa của việc tạo khóa ngoại như sau: nếu hai bảng phục vụ cho việc lưu trữ thông tin có liên quan với nhau, cần phải đảm bảo rằng mối quan hệ này sẽ luôn luôn chính xác. Ví dụ, tài liệu “vận đơn” chứa tiêu đề chung (ngày, số vận đơn, v.v.) và tập hợp các bản ghi chi tiết (mô tả hàng hóa, số lượng, v.v.).
Để lưu trữ tài liệu như vậy, hai bảng được tạo trong cơ sở dữ liệu - một bảng để lưu trữ tiêu đề của vận đơn, và bảng thứ hai - để lưu trữ nội dung của vận đơn - các bản ghi về hàng hóa và số lượng của chúng. Các bảng như vậy được gọi là bảng chính và bảng phụ thuộc hoặc bảng-master và bảng-chi tiết.
Theo lẽ thường, nội dung của vận đơn không thể tồn tại mà không có sự hiện diện của tiêu đề của nó. Nói cách khác, chúng ta không thể chèn một bản ghi về hàng hóa nếu chúng ta chưa tạo tiêu đề của vận đơn, và chúng ta không thể xóa một bản ghi tiêu đề nếu có các bản ghi về hàng hóa. Để hiện thực hóa hành vi như vậy, bảng tiêu đề và bảng chi tiết được kết nối bằng ràng buộc khóa ngoại.
Hãy xem xét ý nghĩa của việc đặt ràng buộc khóa ngoại bằng ví dụ về các bảng chứa thông tin về vận đơn. Vì mục đích này, chúng ta sẽ tạo hai bảng để lưu trữ vận đơn - bảng TITLE để lưu trữ tiêu đề và bảng INVENTORY để lưu trữ thông tin về hàng hóa có trong vận đơn.
CREATE TABLE TITLE( ID_TITLE INTEGER NOT NULL Primary Key, DateNakl DATE, NumNakl INTEGER, NoteNakl VARCHAR(255));
Lưu ý rằng chúng ta đã xác định khóa chính trong bảng tiêu đề dựa trên trường ID_TITLE ngay lập tức. Các trường còn lại của bảng TITLE chứa thông tin đơn giản về tiêu đề vận đơn - ngày, số, ghi chú.
Bây giờ hãy xác định bảng để lưu trữ thông tin về hàng hóa có trong vận đơn:
CREATE TABLE INVENTORY( ID_INVENTORY INTEGER NOT NULL PRIMARY KEY, FK_TITLE INTEGER NOT NULL, ProductName VARCHAR (255), Kolvo DOUBLE PRECISION, Positio INTEGER);
Hãy xem những trường nào được đưa vào bảng INVENTORY. Đầu tiên, đó là ID_INVENTORY - khóa chính của bảng này. Sau đó là trường số nguyên FK_TITLE phục vụ như tham chiếu đến định danh ID_TITLE của tiêu đề trong bảng tiêu đề vận đơn. Sau đó là các trường ProductName, Kolvo và Positio mô tả mô tả hàng hóa, số lượng và vị trí trong vận đơn. Trường FK_TITLE là quan trọng nhất cho ví dụ của chúng ta. Nếu chúng ta muốn xuất thông tin về hàng hóa của một vận đơn cụ thể, chúng ta nên sử dụng truy vấn sau, trong đó tham số mas_ID_TITLE xác định định danh tiêu đề:
SELECT * FROM INVENTORY I1 WHERE I1.FK_TITLE=?mas_ID_TITLE
Về cơ bản, trong tình huống được mô tả, không có gì ngăn cản việc điền vào bảng INVENTORY các bản ghi tham chiếu đến các bản ghi không tồn tại trong bảng TITLE. Ngoài ra, không có gì cản trở việc xóa tiêu đề của vận đơn đã tồn tại, vì vậy các bản ghi về hàng hóa có thể trở thành “vô chủ”. Máy chủ sẽ không cấm thực hiện tất cả các thao tác chèn và xóa này. Do đó, việc kiểm soát tính toàn vẹn dữ liệu trong cơ sở dữ liệu hoàn toàn được đặt lên ứng dụng khách. Tuy nhiên, bạn biết rằng nhiều ứng dụng được phát triển, có thể, bởi các lập trình viên khác nhau có thể làm việc với một cơ sở dữ liệu, điều này có thể dẫn đến việc diễn giải dữ liệu khác nhau và gây ra lỗi. Do đó, điều cần thiết là đặt ràng buộc rõ ràng rằng chỉ những bản ghi về hàng hóa có tham chiếu chính xác đến tiêu đề vận đơn mới có thể được đưa vào bảng INVENTORY. Đây, trên thực tế, là ràng buộc khóa ngoại cho phép chỉ chèn những giá trị nằm trong bảng khác vào các trường được đưa vào ràng buộc.
Ràng buộc như vậy có thể được tạo bằng khóa ngoại. Trong ví dụ đã cho, chúng ta phải đặt ràng buộc khóa ngoại cho trường FK_TITLE và liên kết nó với khóa chính ID_TITLE trong bảng TITLE. Chúng ta có thể thêm khóa ngoại vào bảng đã tồn tại bằng lệnh sau:
ALTER TABLE INVENTORY ADD CONSTRAINT fktitle1 FOREIGN KEY(FK_TITLE) REFERENCES TITLE(ID_TITLE)
Thường khi thêm khóa ngoại, lỗi xuất hiện - object is in use. Vấn đề là để tạo khóa ngoại, chúng ta phải mở cơ sở dữ liệu ở chế độ burst - sao cho không có người dùng nào khác cùng lúc. Chúng ta cũng không nên tham chiếu đến bảng đã được sửa đổi - điều này có thể gây ra lỗi object is in use.
Ở đây INVENTORY là tên của bảng mà ràng buộc khóa ngoại được đặt cho; fktitle1 là tên của khóa ngoại; FK_TITLE - các trường tạo nên khóa ngoại; TITLE là tên của bảng cung cấp các giá trị (cơ sở tham chiếu) cho khóa ngoại; ID_TITLE - các trường của khóa chính hoặc khóa duy nhất trong bảng TITLE, đóng vai trò là cơ sở tham chiếu cho khóa ngoại. Cú pháp đầy đủ của ràng buộc khóa ngoại (với khả năng tạo ràng buộc dựa trên nhiều trường) được đưa ra dưới đây:
= [CONSTRAINT constraint] FOREIGN KEY ( col [, col …]) REFERENCES other_table [( other_col [, other_col …])] [ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}] [ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
Như bạn có thể thấy, các định nghĩa chứa một tập hợp lớn các tùy chọn. Để bắt đầu, hãy xem xét định nghĩa cơ bản của khóa ngoại, thường được sử dụng nhất trong các cơ sở dữ liệu thực tế, và sau đó chúng ta sẽ phân tích các tùy chọn có thể.
Dạng khai báo của ràng buộc khóa ngoại thường được sử dụng khi một tập hợp các trường (col [, col …]), tạo nên ràng buộc, được chỉ định; cũng như other_table chứa danh sách các giá trị có thể cho khóa ngoại trong các trường [(other_col [, other_col …]).
Đây là ví dụ về định nghĩa như vậy khi tạo bảng:
CREATE TABLE Inventory2( … FK_TABLE INTEGER NOT NULL CONSTRAINT fkinv REFERENCES TITLE(ID_TITLE) …);
Chú ý rằng trong định nghĩa này, các từ khóa FOREIGN KEY được bỏ qua, cũng như trường duy nhất FK_TITLE được ngụ ý sử dụng làm khóa ngoại. Một dạng đầy đủ hơn của việc tạo khóa ngoại đồng thời với bảng được đưa ra trong ví dụ sau:
CREATE TABLE Inventory2( … FK_TABLE INTEGER NOT NULL, CONSTRAINT fkinv FOREIGN KEY (FK_TABLE) REFERENCES TITLE(ID_TITLE) …);
Sử dụng NULL trong các trường của khóa ngoại
Trong các trường, dựa trên đó khóa ngoại được tạo, được phép áp dụng các trường NULL. Khả năng này được thêm vào để cho phép tham chiếu lẫn nhau. Ví dụ, nếu có hai bảng tham chiếu lẫn nhau bằng khóa ngoại. Nếu chúng ta không cho phép tham chiếu trống (tức là NULL) trong các khóa ngoại này, sẽ không thể thêm bất kỳ bản ghi nào vào các bảng được liên kết: để thêm bản ghi vào bảng đầu tiên, cần phải có bản ghi trong bảng thứ hai, và ngược lại.
Sử dụng NULL làm tham chiếu trống cho phép tạo tham chiếu lẫn nhau của hai bảng tham chiếu chéo, và cũng lưu trữ các cấu trúc phân cấp trong các bảng quan hệ - tại đó các nút gốc tham chiếu đến các bản ghi “trống” (tức là chỉ chứa NULL).
Các khả năng mở rộng của hỗ trợ toàn vẹn tham chiếu bằng khóa ngoại
Thông thường, biến thể khai báo của ràng buộc khóa ngoại là khá đủ, máy chủ chỉ theo dõi rằng sẽ không thể chèn các giá trị không chính xác vào bảng có khóa ngoại hoặc - khi cố gắng làm điều đó, một lỗi sẽ xuất hiện. Nhưng InterBase cho phép thực hiện một tập hợp các thao tác tự động khi thay đổi / xóa khóa ngoại. Với mục đích này, tập hợp các tùy chọn khóa ngoại sau được sử dụng:
[ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}] [ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
Các tùy chọn này cho phép xác định các thao tác khác nhau khi cập nhật hoặc xóa các giá trị khóa ngoại.
Ví dụ, chúng ta có thể đặt rằng khi xóa khóa chính trong bảng chính, tất cả các bản ghi có cùng khóa ngoại trong bảng phụ sẽ bị xóa. Trong trường hợp này, chúng ta phải xác định khóa ngoại theo cách sau:
ALTER TABLE INVENTORY ADD CONSTRAINT fkautodel FOREIGN KEY (FK_TITLE) REFERENCES TITLE(ID_TITLE) ON DELETE CASCADE
Thực tế, để triển khai các thao tác này, có một trigger hệ thống thực hiện các thao tác nhất định. Trong bảng 1.2 có mô tả về các thao tác của các tùy chọn khác nhau (chú ý rằng các tùy chọn NO ACTION|CASCADE|SET DEFAULT|SET NULL không thể được sử dụng trong một mệnh đề ON XXX).
Bảng 1.2
| Sự kiện | Thao tác | |||
| NO ACTION | CASCADE | SET DEFAULT | SET NULL | |
| ON DELETE | Khi xóa khóa ngoại không làm gì - được sử dụng mặc định | Khi xóa, xóa tất cả các bản ghi liên quan từ bảng phụ | Khi thay đổi đặt trường khóa ngoại làm giá trị mặc định |
Khi thay đổi đặt trường khóa ngoại thành NULL |
| ON UPDATE | Khi thay đổi không làm gì - được sử dụng mặc định | Khi thay đổi một bản ghi, thay đổi tất cả các bản ghi liên quan trong bảng phụ | Khi xóa, đặt trường khóa ngoại làm giá trị mặc định |
Khi xóa đặt trường khóa ngoại thành NULL |
Nếu chúng ta không chỉ định gì hoặc chỉ định NO ACTION, chúng ta phải tự chăm sóc việc thay đổi khóa ngoại (trong trường hợp thay đổi khóa chính), và khi xóa khóa chính, chúng ta nên xóa các bản ghi từ bảng phụ trước. Hãy rất cẩn thận khi sử dụng tùy chọn CASCADE: việc sử dụng bất cẩn của nó có thể dẫn đến việc xóa một số lượng lớn các bản ghi liên quan.
Ràng buộc CHECK
Một trong những ràng buộc hữu ích nhất trong cơ sở dữ liệu là ràng buộc check. Chức năng của nó rất đơn giản - kiểm tra giá trị được chèn vào bảng theo bất kỳ điều kiện nào và theo việc thực hiện điều kiện này, chèn dữ liệu hoặc không. Cú pháp của nó khá đơn giản:
= [CONSTRAINT constraint] CHECK ( )}
Ở đây constraint là tên của ràng buộc; là điều kiện tìm kiếm, trong đó giá trị được chèn / cập nhật có thể được sử dụng làm tham số. Nếu điều kiện tìm kiếm được thỏa mãn, được phép chèn / cập nhật giá trị này, nếu không - một lỗi sẽ xuất hiện. Ví dụ đơn giản nhất về check:
create table checktst( ID integer CHECK(ID>0));
Check này xác định xem giá trị được chèn / cập nhật của trường ID có lớn hơn không, và tùy thuộc vào kết quả cho phép chèn / cập nhật giá trị mới hoặc thông báo về lỗi (xem chương “Extended capabilities of language of InterBase stored procedures " (phần 1)).
Cũng có các biến thể phức tạp hơn của checks. Cú pháp đầy đủ của điều kiện tìm kiếm như sau:
= {
{ | ()}
| [NOT] BETWEEN AND
| [NOT] LIKE [ESCAPE ]
| [NOT] IN ( [ , …] | )
| IS [NOT] NULL
| {[NOT] {= | < | >} | >= | <=}
{ALL | SOME | ANY} ()
| EXISTS ( )
| SINGULAR ( )
| [NOT] CONTAINING
| [NOT] STARTING [WITH]
| ()
| NOT
| OR
| AND }
Do đó, CHECK cung cấp một tập hợp lớn các tùy chọn để kiểm tra các giá trị được chèn / cập nhật. Bạn nên nhớ về các ràng buộc sau khi sử dụng CHECK:
- Dữ liệu cho CHECK chỉ được lấy từ một bản ghi hiện tại. Bạn không nên lấy dữ liệu cho biểu thức trong CHECK từ các bản ghi khác của cùng một bảng - chúng có thể bị thay đổi bởi những người dùng khác
- Một trường chỉ có thể có một ràng buộc CHECK
- Nếu cho định nghĩa trường, một domain có ràng buộc CHECK domain được sử dụng, nó không thể được định nghĩa lại ở mức trường cụ thể trong bảng. Phải nói rằng CHECK được triển khai bởi các trigger hệ thống, do đó chúng ta phải cẩn thận hơn khi sử dụng các điều kiện rất dài, có thể làm chậm đáng kể các quá trình chèn và cập nhật các bản ghi.
Xóa các ràng buộc
Rất thường xuyên, chúng ta xóa các ràng buộc khác nhau vì nhiều lý do khác nhau. Để xóa một ràng buộc, chúng ta nên sử dụng câu lệnh ALTER TABLE có dạng sau: ALTER TABLE tablename DROP CONSTRAINT constraintname
constraintname là tên của ràng buộc cần được xóa. Nếu một tên nhất định được chỉ định khi tạo ràng buộc, chúng ta nên sử dụng nó, nhưng nếu không, chúng ta phải mở bất kỳ công cụ quản trị InterBase nào, tìm kiếm tất cả các ràng buộc liên quan đến nó và tìm ra tên hệ thống mà InterBase đã tạo cho ràng buộc cần thiết.
Cần lưu ý rằng chỉ có chủ sở hữu của bảng hoặc quản trị viên hệ thống SYSDBA mới có thể xóa các ràng buộc.