1

我有两张桌子。这些表之间有两个关系。

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 不想使用它。

有没有更好的解决方案来完成这个过程?

4

4 回答 4

2

使用ON DELETE CASCADE. 它会自动删除引用行。

于 2009-03-19T17:31:10.910 回答
2

您有以下选择:

  • 就像您现在所做的那样,在两个语句中删除。先从 Table2 中删除。

  • 如果您的数据库品牌支持多表DELETE语法(例如 MySQL),则在一个语句中从两个表中删除。这不是标准的 SQL,但它很方便。

  • 使用级联引用完整性约束(我了解您的 DBA 已取消此选项)。

  • 在 Table1 上编写一个触发器BEFORE DELETE,以删除 Table2 中的任何引用或将其设置为 NULL。请咨询您的 DBA,看看这是否比级联 RI 约束更可接受。

最后,我建议与您的 DBA 交谈并提出您在此处提出的相同问题。找出他/她希望您使用的解决方案。StackOverflow 上的人可以回答技术问题,但听起来您正在处理IT 政策问题

于 2009-03-19T17:50:39.100 回答
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
于 2009-03-19T17:33:27.893 回答
0

我知道的两种方法:

  1. 您可以使用 ON DELETE CASCADE

  2. 编写您的 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
    
于 2009-03-19T17:47:47.063 回答