Удалить строки из двух таблиц - PullRequest
1 голос
/ 19 марта 2009

У меня есть две таблицы. Эти таблицы имеют два отношения между ними.

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)

Я знаю, что мог бы использовать ON DELETE SET NULL для table2. Таким образом, я мог бы затем найти все строки с нулевым значением в ID_XPTO2 и удалить их, но администратор БД не хочет его использовать.

Есть ли лучшее решение для этого процесса?

Ответы [ 4 ]

2 голосов
/ 19 марта 2009

У вас есть следующие варианты:

  • Удалить в двух утверждениях, как вы делаете сейчас. Сначала удалите из таблицы 2.

  • Удалить из двух таблиц в одном операторе, если ваш бренд базы данных поддерживает синтаксис DELETE для нескольких таблиц (например, MySQL). Это не стандартный SQL, но он удобен.

  • Использовать каскадные ограничения ссылочной целостности (я так понимаю, ваш администратор баз данных исключил эту опцию).

  • Запишите триггер BEFORE DELETE в Таблицу1, чтобы удалить или установить NULL любую ссылку в Таблице2. Проконсультируйтесь с вашим администратором базы данных, чтобы выяснить, является ли это более приемлемым, чем каскадные ограничения RI.

Наконец, я бы посоветовал поговорить с вашим администратором баз данных и задать тот же вопрос, который вы задали здесь. Узнайте, какое решение он / она предпочитает использовать. Люди в StackOverflow могут отвечать на технические вопросы, но похоже, что вы имеете дело с вопросом политики ИТ .

2 голосов
/ 19 марта 2009

Используйте ON DELETE CASCADE. Он автоматически удалит ссылки на строки.

0 голосов
/ 19 марта 2009

Два метода, которые я знаю:

  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
    
0 голосов
/ 19 марта 2009

Почему бы вам не использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...