Q: Tôi có phải tắt các ràng buộc cho việc chèn xảy ra không?
A: Trong Oracle, không, không phải nếu ràng buộc khoá ngoại là DEFERRABLE
(xem ví dụ dưới đây)
Đối với Oracle:
SET CONSTRAINTS ALL DEFERRED;
INSERT INTO Departments values ('foo','dummy');
INSERT INTO Employees values ('bar','foo');
UPDATE Departments SET EmployeeID = 'bar' WHERE DepartmentID = 'foo';
COMMIT;
Hãy giải nén rằng:
- (phải tự động tắt)
- trì hoãn việc thực thi ràng buộc khóa ngoài
- chèn một hàng để bảng cục với một "dummy" giá trị cho cột FK
- chèn một hàng để bảng Employee với FK tham chiếu đến cục
- thay thế "dummy" giá trị tại Khoa FK với tài liệu tham khảo thực
- bật lại thi hành những hạn chế
GHI CHÚ: vô hiệu hóa một ràng buộc khoá ngoại có hiệu lực cho tất cả các phiên, trì hoãn một hạn chế là ở mức độ giao dịch (như trong ví dụ), hoặc ở cấp phiên (ALTER SESSION SET CONSTRAINTS=DEFERRED;
)
Oracle đã cho phép các ràng buộc khóa ngoài được định nghĩa là DEFERRABLE trong ít nhất một thập kỷ. Tôi xác định tất cả các ràng buộc khóa ngoại (như là một vấn đề của khóa học) là DEFERRABLE INITIALLY IMMEDIATE. Điều đó giữ cho hành vi mặc định như mọi người mong đợi, nhưng cho phép thao tác mà không yêu cầu khóa ngoài bị vô hiệu hóa.
thấy AskTom:
http://www.oracle.com/technology/oramag/oracle/03-nov/o63asktom.html
thấy AskTom: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:10954765239682
also see: http://www.idevelopment.info/data/Oracle/DBA_tips/Database_Administration/DBA_12.shtml
[EDIT]
A: Trong Microsoft SQL Server, bạn có thể không trì hoãn các ràng buộc khóa ngoại như bạn có thể trong Oracle. Việc vô hiệu hóa và kích hoạt lại ràng buộc khoá ngoại là một cách tiếp cận, nhưng tôi rùng mình trước viễn cảnh 1) tác động hiệu suất (ràng buộc khóa ngoài được kiểm tra cho bảng TOÀN BỘ khi ràng buộc được kích hoạt lại), 2) xử lý ngoại lệ nếu (khi nào?) việc kích hoạt lại ràng buộc không thành công. Lưu ý rằng việc vô hiệu hóa ràng buộc sẽ ảnh hưởng đến tất cả các phiên, do đó, trong khi ràng buộc bị vô hiệu hóa, các phiên khác có khả năng chèn và cập nhật các hàng sẽ gây ra sự ràng buộc của ràng buộc thất bại.
Với SQL Server, cách tiếp cận tốt hơn là xóa ràng buộc NOT NULL và cho phép NULL làm chỗ dành sẵn trong khi các hàng đang được chèn/cập nhật.
Đối với SQL Server:
-- (with NOT NULL constraint removed from Departments.EmployeeID)
insert into Departments values ('foo',NULL)
go
insert into Employees values ('bar','foo')
go
update Departments set EmployeeID = 'bar' where DepartmentID = 'foo'
go
[/ EDIT]
Điều này có vẻ giống như một sơ đồ xa lạ với tôi, bạn có thể giải thích lý do tại sao bạn có mối quan hệ theo cách này? – Bob
Có phải EmployeeId trong bảng phân công của bạn giống như một người quản lý bộ phận hay không? –
Trong Oracle, "thủ thuật" là xác định khoá ngoại (DEFERRABLE). – spencer7593