2009-09-28 3 views
5

У меня есть головоломка (по крайней мере, для меня), которую я надеюсь, в основном потому, что я еще не являюсь мастером SQL вселенной. В основном у меня есть три таблицы:Избегайте курсора базы данных в SQL Server

В таблице А, в таблице B, и в таблице С.

Таблица С имеет FK (Foriegn ключ) в таблице B, который имеет FK в таблице А. (Каждый из этих многих к одному)

Мне нужно удалить запись из таблицы A и, конечно, все соответствующие записи из таблиц B и C. В прошлом я использовал курсор для этого, выбрав все записи в таблице B и циклически перемещаясь по каждому из них, чтобы удалить все их соответствующие записи в таблице C. Теперь это работает - и работает нормально, но я подозреваю/надеюсь, что есть лучший способ добиться этого эффекта без использования курсоров. Итак, это мой вопрос - как я могу это сделать без использования курсора, или это можно сделать?

(Пожалуйста, дайте мне знать, если я не был понятен - я постараюсь решить вопрос).

ответ

11

Объявите ваши FOREIGN KEY с, как ON DELETE CASCADE

+3

@ OP- это приведет к удалению любых записей в таблицах B и C, если запись, содержащая ссылки, удалена в таблице A –

2

При создании внешнего ключа для обеих таблиц вы можете указать ON DELETE CASCADE и он будет заботиться об этом для вас, когда вы удаляете запись в A.

8

Вы можете сделать это несколько способов ...

  • Вы могли бы просто использовать cascading deletes на своих внешних ключей.

CREATE TABLE TableB 
    (FKColumn INT, 
    CONSTRAINT MyFk FOREIGN KEY (FKColumn) 
     REFERENCES TableA(PKColumn) ON DELETE CASCADE) 
  • Вы можете использовать удаление триггеров на каждой таблицы, чтобы удалить соответствующие записи.

CREATE TRIGGER cascade_triggerA 
    ON TableA 
    FOR DELETE 
AS 
BEGIN 

    DELETE TableB 
    FROM TableB JOIN DELETED ON TableB.FKColumn = DELETED.PKColumn 

END 

CREATE TRIGGER cascade_triggerB 
    ON TableB 
    FOR DELETE 
AS 
BEGIN 

    DELETE TableC 
    FROM TableC JOIN DELETED ON TableC.FKColumn = DELETED.PKColumn 

END 
  • Если вы используете сервер MS SQL, вы можете также использовать INSTEAD OF DELETE триггеры. В этом случае вы создадите триггер только на TableA - и в триггере поместите всю логику для удаления записей из всех трех таблиц.

В любом из перечисленных случаев вы просто удаляете запись из таблицы A, и пусть каскадные и триггеры позаботятся об остальном.

5

Ответы, уже предоставленные (Cascading Deletes and Triggers), отличные, но вы можете работать в среде, где это не вариант. Если это так, ниже - это чисто SQL-решение. Этот пример касается исключительно синтаксиса DELETE. В реальном мире вы, вероятно, переносите это в транзакцию и реализуете ее как хранимую процедуру.

-- 
DECLARE @Param_PK_TableA int 
SET  @Param_PK_TableA = 1500 


------------------------------- 
-- TABLE C -------------------- 
DELETE TableC 

FROM TableC 

    INNER JOIN TableB 
      ON TableB.TableB_ID = TableC.TableB_ID 

    INNER JOIN TableA 
      ON TableA.TableA_ID = TableB.TableA_ID 

WHERE 
    (TableA.TableA_ID = @Param_PK_TableA) 



------------------------------- 
-- TABLE B -------------------- 
DELETE TableB 

FROM TableB 

    INNER JOIN TableA 
      ON TableA.TableA_ID = TableB.TableA_ID 

WHERE 
    (TableA.TableA_ID = @Param_PK_TableA) 



------------------------------- 
-- TABLE A -------------------- 
DELETE TableA 

WHERE 
    (TableA.TableA_ID = @Param_PK_TableA) 
Смежные вопросы