Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Menerapkan Persyaratan Keduanya, Salah Satunya, tetapi Bukan Null dalam Basis Data

Jawaban Ypercube baik-baik saja, kecuali ini sebenarnya dapat dilakukan murni melalui integritas deklaratif sambil menjaga tabel terpisah. Triknya adalah menggabungkan KUNCI ASING melingkar yang ditangguhkan dengan sedikit denormalisasi kreatif:

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;

Memasukkan Teks dilakukan seperti ini:

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

Memasukkan Dokumen seperti ini:

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

Dan memasukkan Teks dan Dokumen seperti ini:

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

Namun, mencoba memasukkan Instruksi saja gagal di komit:

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

Mencoba memasukkan "jenis yang tidak cocok" juga gagal di komit:

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

Dan tentu saja, mencoba memasukkan nilai buruk ke dalam Instruksi gagal (kali ini sebelum komit):

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. System.InvalidCastException:Objek tidak dapat dilemparkan dari DBNull ke tipe lain

  2. Mengapa Oracle tidak menunjukkan bagian bilangan bulat dari desimal

  3. Cara menggunakan Tabel Oracle PLSQL (Array asosiatif atau tabel indeks menurut)

  4. Apakah Oracle sqlldr memproses beberapa INFILE secara paralel?

  5. Bagaimana cara menjalankan pekerjaan di oracle?