Ypercube's answer ठीक है, इसके अलावा, वास्तव में, अलग-अलग तालिकाओं को रखते हुए पूरी तरह से घोषणात्मक अखंडता के माध्यम से किया जा सकता है। ट्रिक यह है कि आस्थगित परिपत्र विदेशी कुंजियों को थोड़ा सा रचनात्मक असामान्यकरण के साथ संयोजित किया जाए:
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;
पाठ सम्मिलित करना इस प्रकार किया जाता है:
INSERT INTO Instruction (InstructionId, TextId) VALUES (1, 1);
INSERT INTO Text (InstructionId) VALUES (1);
COMMIT;
इस तरह दस्तावेज़ सम्मिलित करना:
INSERT INTO Instruction (InstructionId, DocumentId) VALUES (2, 2);
INSERT INTO Document (InstructionId) VALUES (2);
COMMIT;
और टेक्स्ट और डॉक्यूमेंट दोनों को इस तरह से इन्सर्ट करना:
INSERT INTO Instruction (InstructionId, TextId, DocumentId) VALUES (3, 3, 3);
INSERT INTO Text (InstructionId) VALUES (3);
INSERT INTO Document (InstructionId) VALUES (3);
COMMIT;
हालांकि, केवल निर्देश सम्मिलित करने का प्रयास विफल प्रतिबद्धता पर:
INSERT INTO Instruction (InstructionId, TextId) VALUES (4, 4);
COMMIT; -- Error (FOREIGN KEY violation).
"बेमेल प्रकार" डालने का प्रयास भी विफल प्रतिबद्धता पर:
INSERT INTO Document (InstructionId) VALUES (1);
COMMIT; -- Error (FOREIGN KEY violation).
और निश्चित रूप से, निर्देश में खराब मान डालने का प्रयास विफल (इस बार प्रतिबद्ध होने से पहले):
INSERT INTO Instruction (InstructionId, TextId) VALUES (5, 6); -- Error (CHECK violation).
INSERT INTO Instruction (InstructionId) VALUES (7); -- Error (CHECK violation).