Löschen von Zeilen aus zwei Tabellen
-
20-08-2019 - |
Frage
Ich habe zwei Tabellen. Diese Tabellen haben zwei Beziehung zwischen ihnen.
Table 1
* ID_XPTO (PK)
* Detail
Table 2
* ID_XPTO (FK) (PK)
* ID_XPTO2 (FK) (PK)
Diese beiden Beziehungen besteht.
Table 1 -< Table2
Table 1 -< Table2
Meine Frage ist, dass ich eine Zeile in der Tabelle löschen muß, 1. Ich bin derzeit dabei,
declare @table Table (xptoTable2 int)
insert into @table
select ID_XPTO2
from Table2
where ID_XPTO = @ID_XPTO
delete from Table2
where ID_XPTO = @ID_XPTO
delete from Table
where ID_XPTO in (select xptoTable2from @table)
Ich weiß, dass ich ON DELETE SET NULL auf table2 verwenden könnte. Auf diese Weise konnte ich dann für alle Zeilen mit Nullwert auf ID_XPTO2 suchen und löschen, aber DBA nicht will, es nicht benutzen.
Gibt es eine bessere Lösung, diesen Prozess zu tun?
Lösung
Sie haben folgende Möglichkeiten:
-
in zwei Anweisungen löschen, wie Sie jetzt tun. Löschen von Table2 zuerst.
-
Löschen aus zwei Tabellen in einer Erklärung, wenn Sie Ihre Marke von Datenbank-Multi-Table
DELETE
Syntax (z MySQL) unterstützt. Dies ist nicht Standard-SQL, aber es ist praktisch. -
Mit kaskadierenden referenziellen Integrität (Ich verstehe Ihre DBA hat diese Option nixed).
-
einen Trigger
BEFORE DELETE
auf Table1 schreiben, zu löschen oder NULL jede Bezugnahme in Tabelle 2 eingestellt. Überprüfen Sie mit Ihrem DBA zu sehen, ob dies mehr akzeptabel als die Kaskadierung RI Einschränkungen ist.
Schließlich würde ich Ihnen raten zu Ihrem DBA sprechen und die gleiche Frage Sie hier gefragt. Finden Sie heraus, was Lösung, die er / sie würde es vorziehen, den Sie zu verwenden. Leute auf Stackoverflow können technische Fragen beantworten, aber es klingt wie Sie mit einer IT-Richtlinien Frage beschäftigen .
Andere Tipps
Mit ON DELETE CASCADE
. Es wird automatisch löschen referenzierenden Zeilen.
Warum gehst du nicht verwenden ON DELETE CASCASE
?
DROP TABLE t_f
DROP TABLE t_m
CREATE TABLE t_m (id INT NOT NULL IDENTITY PRIMARY KEY , value VARCHAR(50))
CREATE TABLE t_f (id INT NOT NULL IDENTITY PRIMARY KEY, m INT, CONSTRAINT fk_m FOREIGN KEY (m) REFERENCES t_m(id) ON DELETE CASCADE)
INSERT INTO t_m (value) VALUES ('test')
INSERT INTO t_f (m) VALUES (1)
DELETE FROM t_m
SELECT * FROM t_m
SELECT * FROM t_f
id value
------------ ------
0 rows selected
id m
------------ ------
0 rows selected
Zwei Methoden, die ich kenne:
-
Sie könnten verwenden ON DELETE CASCADE
-
Schreiben Sie eine SQL nach sich aufzuräumen dh:
DECLARE @DetailCriteria ... SET @DetailCriteria = '....' BEGIN TRAN -- First clear the Table2 of any child records DELETE FROM Table2 WHERE ID_XPTO IN (SELECT ID_XPTO FROM Table1 WHERE Detail = @DetailCriteria) OR ID_XPTO2 IN (SELECT ID_XPTO FROM Table1 WHERE Detail = @DetailCriteria) -- Next clear Table2 (which will delete fine because you've followed the referential chain) DELETE FROM Table1 WHERE Detail = @DetailCriteria -- commit if you're happy (should check @@ERROR first) COMMIT