2013-07-31 54 views
8

Tôi có sau DDL mà tôi đang sử dụng với SQL Server 2012:Tôi có cần phải chỉ định ON DELETE NO ACTION trên Khóa Ngoại của tôi không?

CREATE TABLE Subject (
    [SubjectId] INT IDENTITY (1, 1) NOT NULL, 
    [Name] NVARCHAR (50) Not NULL, 
    CONSTRAINT [PK_Subject] PRIMARY KEY CLUSTERED ([SubjectId] ASC) 
)   

CREATE TABLE Topic (
    [TopicId] INT IDENTITY (1, 1) NOT NULL, 
    [Name] NVARCHAR (50) NOT NULL, 
    [SubjectId] INT NOT NULL, 
    CONSTRAINT [PK_Topic] PRIMARY KEY CLUSTERED ([TopicId] ASC) 
) 
ALTER TABLE [Topic] WITH CHECK ADD CONSTRAINT [FK_TopicSubject] 
    FOREIGN KEY([SubjectId]) REFERENCES [Subject] ([SubjectId]) 
    ON DELETE NO ACTION 

Những gì tôi muốn là cho SQL Server để ngăn chặn tôi xóa một phụ huynh nếu một tham chiếu đến mẹ mà tồn tại trong con? Ví dụ: tôi muốn xóa trên subjectID = 3 trong Chủ đề thất bại nếu có trẻ em có SubjectId là 3.

Vì điều này tôi không rõ ràng và dường như không tìm thấy câu trả lời. Tôi có cần phải thêm "DELETE NO ACTION" hoặc tôi không thể xóa ba từ này.

Tôi đang đặt câu hỏi này như trong một câu hỏi tương tự, tôi đã có câu trả lời rằng tôi nên xác định trình kích hoạt trên cấp độ gốc. Tuy nhiên tôi nghĩ rằng chỉ cần xác định khóa ngoại sẽ ngăn tôi xóa cha mẹ nếu một đứa trẻ tồn tại.

Trả lời

19

Từ trang column_constraint trên MSDN:

ON DELETE {NO HÀNH ĐỘNG | CASCADE | SET NULL | SET DEFAULT}

Chỉ định hành động nào xảy ra với các hàng trong bảng bị thay đổi, nếu những hàng hàng có mối quan hệ tham chiếu và hàng được tham chiếu bị xóa từ bảng chính. Mặc định là KHÔNG CÓ ACTION.

Vì vậy, bạn có thể elide ON DELETE NO ACTION nếu bạn thích và nó sẽ hoạt động giống nhau.

KHÔNG HÀNH ĐỘNG nghĩa là không có gì sẽ xảy ra khi bạn xóa khỏi bảng Chủ đề của bạn vào bảng Chủ đề. Trong trường hợp đó, nếu có một hàng trong Topic cho một SubjectId đã cho, bạn không thể xóa nó khỏi nó mà không phá vỡ tính toàn vẹn tham chiếu, vì vậy Delete sẽ được khôi phục.

Thêm từ MSDN:

KHÔNG HÀNH ĐỘNG - SQL Server Database Engine đặt ra một lỗi và hành động xóa trên hàng trong bảng cha được cuộn lại.

+0

Dave - Tôi xin lỗi nhưng tôi hơi bối rối bởi "Chỉ định hành động nào xảy ra với các hàng trong bảng bị thay đổi, nếu những hàng đó có mối quan hệ tham chiếu và hàng được tham chiếu bị xóa khỏi bảng cha". Điều này có ý nghĩa gì khi nó liên quan đến các bảng Chủ đề và Chủ đề của tôi? – Melina

+0

Có Chủ đề là Phụ huynh và Chủ đề là bảng con. – DaveShaw

+0

Đã cập nhật câu trả lời của tôi. – DaveShaw

1

Bạn có thể loại bỏ các từ khóa (đây là mặc định)

ON DELETE NO ACTION 

sẽ được tốt hơn để xác định những hành động

ON DELETE CASCADE 

Dưới đây là thông tin thêm này: http://msdn.microsoft.com/en-us/library/aa933119%28v=sql.80%29.aspx

Bạn sẽ phải để viết trình kích hoạt để đảm bảo hàng của trẻ không bị xóa, vì tôi không nghĩ rằng SQL Server có tùy chọn này là ON DELETE RESTRICT

+0

Được rồi, vậy bạn có nói rằng XÓA KHÔNG CÓ HÀNH ĐỘNG giống như tôi không đặt bất kỳ thứ gì? DELETE RESTRICT là một cái gì đó mới vì vậy tôi sẽ cố gắng kiểm tra điều đó. – Melina

+0

Không giới hạn chỉ Oracle? – DaveShaw

+0

@DaveShaw Yup, chỉ nhận ra nó, tôi đã cập nhật tương tự, cảm ơn – Akash

1

tôi sẽ gợi ý cho bạn trong khi bạn có thể bỏ qua trên xóa không có hành động, nó có thể không phải vì lợi ích tốt nhất của bạn để làm như vậy. Việc này được xác định trong định nghĩa bảng có thể ngăn chặn một người nào đó sau đó thêm vào việc xóa tầng trên vì họ thấy rằng bạn dự định sẽ không xảy ra. Điều này đặc biệt đúng khi bạn viết kịch bản chính xác tất cả các đối tượng cơ sở dữ liệu và đặt chúng trong điều khiển nguồn và trình xem mã sẽ thấy rằng có sự khác biệt và hỏi tại sao nó xảy ra.Tất cả quá thường xuyên, mọi người quá háo hức muốn thêm vào xóa thác và phá hủy dữ liệu cần được lưu giữ (như hồ sơ tài chính cho khách hàng không còn giá trị). Họ làm điều này bởi vì họ nhận được lỗi mà không cho phép họ xóa và chỉ muốn thoát khỏi nó thay vì nhận ra rằng điều này là tiết kiệm cho họ từ một sai lầm lớn. Ít nhất nếu bạn có mã cho Xóa Không có hành động trong kịch bản bảng của bạn, người bảo trì trong tương lai sẽ thấy rằng điều này là cố ý và không chỉ là bạn quên thiết lập xóa tầng. Tất nhiên nếu dba của bạn không cho phép xóa tầng (vì nhiều người không và vì lý do tốt!) Thì đây không phải là một vấn đề tiềm ẩn, nhưng việc xác định ý định của bạn thường là một điều tốt để bảo trì.

Các vấn đề liên quan