我有两张桌子。这些表有两种关系。
Table 1
* ID_XPTO (PK)
* Detail
Table 2
* ID_XPTO (FK) (PK)
* ID_XPTO2 (FK) (PK)
这两种关系存在。
Table 1 -< Table2
Table 1 -< Table2
我的问题是我需要删除表1中的一行。我现在正在做,
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)
我知道我可以在table2上使用ON DELETE SET NULL。然后,我可以在ID_XPTO2上搜索所有具有空值的行并删除它们,但DBA不想使用它。
有没有更好的解决方案来完成这个过程?
答案 0 :(得分:2)
使用ON DELETE CASCADE
。它会自动删除引用行。
答案 1 :(得分:2)
您有以下选择:
删除两个语句,正如您现在所做的那样。首先从表2中删除。
如果您的数据库品牌支持多表DELETE
语法(例如MySQL),则从一个语句中的两个表中删除。这不是标准的SQL,但它很方便。
使用级联参照完整性约束(我知道您的DBA已添加此选项)。
在Table1上写一个触发器BEFORE DELETE
,删除或设置表2中的任何引用。请咨询您的DBA,看看这是否比级联RI约束更可接受。
最后,我建议您与您的DBA交谈并询问您在此处提出的相同问题。找出他/她希望您使用的解决方案。 StackOverflow上的人可以回答技术问题,但听起来您正在处理 IT政策问题。
答案 2 :(得分:0)
为什么不使用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
答案 3 :(得分:0)
我所知道的两种方法:
您可以使用ON DELETE CASCADE
编写SQL以便自行清理,即:
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