Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Thực hiện Yêu cầu Cả hai, Một hoặc, nhưng Không rỗng trong Cơ sở dữ liệu

Câu trả lời của Ypercube là tốt, ngoại trừ điều này, trên thực tế, có thể được thực hiện hoàn toàn thông qua tính toàn vẹn khai báo trong khi giữ các bảng riêng biệt. Bí quyết là kết hợp các KEY NGOẠI GIAO hình tròn trì hoãn với một chút bất chuẩn hóa sáng tạo:

CREATE TABLE Instruction (
    InstructionId INT PRIMARY KEY,
    TextId INT UNIQUE,
    DocumentId INT UNIQUE,
    CHECK (
        (TextId IS NOT NULL AND InstructionId = TextId)
        OR (DocumentId IS NOT NULL AND InstructionId = DocumentId)
    )
);

CREATE TABLE Text (
    InstructionId INT PRIMARY KEY,
    FOREIGN KEY (InstructionId) REFERENCES Instruction (TextId) ON DELETE CASCADE
);

CREATE TABLE Document (
    InstructionId INT PRIMARY KEY,
    FOREIGN KEY (InstructionId) REFERENCES Instruction (DocumentId) ON DELETE CASCADE
);

ALTER TABLE Instruction ADD FOREIGN KEY (TextId) REFERENCES Text DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE Instruction ADD FOREIGN KEY (DocumentId) REFERENCES Document DEFERRABLE INITIALLY DEFERRED;

Việc chèn Văn bản được thực hiện như sau:

INSERT INTO Instruction (InstructionId, TextId) VALUES (1, 1);
INSERT INTO Text (InstructionId) VALUES (1);
COMMIT;

Chèn Tài liệu như thế này:

INSERT INTO Instruction (InstructionId, DocumentId) VALUES (2, 2);
INSERT INTO Document (InstructionId) VALUES (2);
COMMIT;

Và chèn cả Văn bản và Tài liệu như thế này:

INSERT INTO Instruction (InstructionId, TextId, DocumentId) VALUES (3, 3, 3);
INSERT INTO Text (InstructionId) VALUES (3);
INSERT INTO Document (InstructionId) VALUES (3);
COMMIT;

Tuy nhiên, cố gắng chèn Chỉ lệnh một mình thì không thành công cam kết:

INSERT INTO Instruction (InstructionId, TextId) VALUES (4, 4);
COMMIT; -- Error (FOREIGN KEY violation).

Cố gắng chèn "loại không khớp" cũng không thành công cam kết:

INSERT INTO Document (InstructionId) VALUES (1);
COMMIT; -- Error (FOREIGN KEY violation).

Và tất nhiên, cố gắng chèn các giá trị không hợp lệ vào Hướng dẫn không thành công (thời gian này trước khi cam kết):

INSERT INTO Instruction (InstructionId, TextId) VALUES (5, 6); -- Error (CHECK violation).
INSERT INTO Instruction (InstructionId) VALUES (7); -- Error (CHECK violation).


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để tìm sự khác biệt b / w các giá trị định dạng TIMESTAMP trong Oracle?

  2. So sánh các nhà cung cấp Oracle .NET bên thứ 3

  3. Thứ tự mặc định khác nhau giữa ORACLE và PostgreSQL

  4. Spring JPA Hibernate:truy vấn SELECT chậm

  5. Các khóa chính và chỉ mục trong ngôn ngữ truy vấn Hive có khả dụng hay không?