2013-07-31 6 views
8

Ich habe folgende DDL, die ich mit SQL Server 2012 bin mit:Muss ich ON DELETE NO ACTION auf meinem Fremdschlüssel angeben?

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 

Was ich will, für den SQL-Server ist, mich zu stoppen einen Elternteil zu löschen, wenn ein Verweis auf den übergeordneten in dem Kind existiert? Zum Beispiel möchte ich eine Löschung auf subjectID = 3 in Betreff, um zu scheitern, wenn es Kinder mit SubjectId von 3 gibt.

Dafür bin ich unklar und kann nicht scheinen, die Antwort zu finden. Muss ich "DELETE NO ACTION" hinzufügen oder kann ich diese drei Wörter nicht entfernen.

Ich stelle diese Frage, da ich in einer ähnlichen Frage eine Antwort hatte, dass ich einen Auslöser auf dem Eltern definieren sollte. Ich dachte jedoch, nur den Fremdschlüssel zu definieren würde mich stoppen, den Elternteil zu löschen, wenn ein Kind existiert.

Antwort

19

Von der column_constraint Seite auf MSDN:

ON DELETE {NO ACTION | CASCADE | SET NULL | SET DEFAULT}

Gibt an, welche Aktion Zeilen in der Tabelle kommt vor, dass geändert wird, wenn diese Zeilen haben eine Referenzbeziehung und die referenzierte Zeile aus der Elterntabelle gelöscht wird. Der Standardwert ist KEINE AKTION.

So können Sie Elide ON DELETE NO ACTION wenn Sie mögen und es wird genauso funktionieren.

KEINE AKTION bedeutet, dass nichts passiert, wenn Sie von Ihrer Betreff-Tabelle in die Themen-Tabelle löschen. In diesem Fall, wenn eine Zeile in Topic für eine gegebene SubjectId existiert, können Sie nicht löschen, ohne die referenzielle Integrität zu zerstören, so dass das Löschen rückgängig gemacht wird.

Mehr von MSDN:

NO ACTION - Der SQL Server-Datenbank-Engine löst einen Fehler und die Löschaktion auf der Zeile in der übergeordneten Tabelle wird zurückgesetzt.

+0

Dave - Es tut mir leid, aber ich bin ein wenig verwirrt von "Gibt an, welche Aktion mit Zeilen in der Tabelle passiert, die geändert wird, wenn diese Zeilen eine referenzielle Beziehung haben und die referenzierte Zeile aus der übergeordneten Tabelle gelöscht wird." Was bedeutet das in Bezug auf meine Themen- und Thementische? – Melina

+0

Ja Betreff ist das Elternteil und Thema ist die Kindtabelle. – DaveShaw

+0

Meine Antwort wurde aktualisiert. – DaveShaw

1

können Sie die Schlüsselwörter entfernen (dies ist die Standardeinstellung)

ON DELETE NO ACTION 

wäre besser, um diese Aktionen festlegen

ON DELETE CASCADE 

hier weitere Informationen dazu: http://msdn.microsoft.com/en-us/library/aa933119%28v=sql.80%29.aspx

Sie müssen um einen Trigger zu schreiben, um sicherzustellen, dass untergeordnete Zeilen nicht gelöscht werden, da ich denke, dass SQL Server diese Option ON DELETE RESTRICT

nicht hat
+0

Okay, also sagst du, DELETE NO ACTION ist das selbe wie das, was ich nicht mache? DELETE RESTRICT ist etwas Neues, also werde ich versuchen, das zu überprüfen. – Melina

+0

Wird Oracle nicht eingeschränkt? – DaveShaw

+0

@DaveShaw Yup, realisierte es gerade, ich habe das gleiche aktualisiert, danke – Akash

1

Ich werde Ihnen vorschlagen, dass, während Sie die auf löschen keine Aktion überspringen können, könnte es nicht in Ihrem besten Interesse sein, dies zu tun. Wenn dies in der Tabellendefinition angegeben wird, kann später verhindert werden, dass jemand ein Kaskadierungslöschung hinzufügt, weil sie erkannt haben, dass dies nicht beabsichtigt ist. Dies gilt insbesondere dann, wenn Sie alle Datenbankobjekte korrekt skripten und sie in die Quellcodeverwaltung einbetten, und der Code-Überprüfer erkennt, dass ein Unterschied besteht, und fragt, warum das passiert ist.Allzu oft sind die Leute zu eifrig bemüht, Löschkaskaden hinzuzufügen und Daten zu zerstören, die aufbewahrt werden sollten (wie Finanzdaten für einen Kunden, der nicht mehr gültig ist). Sie tun dies, weil sie den Fehler bekommen, der sie nicht löschen lässt und nur loswerden will, anstatt zu realisieren, dass dies ihnen vor einem massiven Fehler bewahrt. Zumindest, wenn Sie den Code für Delete No Action in Ihrem Tabellenskript haben, werden zukünftige Betreuer sehen, dass dies beabsichtigt war und nicht nur, dass Sie vergessen haben, Kaskadenlöschungen einzurichten. Natürlich, wenn Ihr dba keine kaskadierenden Löschungen erlaubt (wie viele nicht und aus gutem Grund!), Dann ist dies kein potentielles Problem, aber die Angabe Ihrer Absicht ist oft eine gute Sache für die Wartbarkeit.

Verwandte Themen