SQL Trigger не может выполнить INSTEAD OF DELETE, но требуется для столбцов ntext, image - PullRequest
3 голосов
/ 01 февраля 2012
CREATE TRIGGER [dbo].[C1_Deletions] ON [dbo].[C1] INSTEAD OF DELETE AS
SET NOCOUNT ON
  IF EXISTS ( SELECT 'True' FROM deleted JOIN C1 ON deleted.ACCOUNTNO = C1.ACCOUNTNO )
   BEGIN
    INSERT INTO [GDeletions].[dbo].[C1] SELECT * FROM deleted
    DELETE C1 FROM C1 INNER JOIN DELETED ON C1.ACCOUNTNO = DELETED.ACCOUNTNO
   END

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

Если я изменяю INSTEAD OF на AFTER, я получаю ошибки о ntext, столбцы изображений не допускаются. Есть ли способ обойти эту проблему? Я не могу быть тем, кто определяет строку удаления, сама программа делает это, мне просто нужен триггер, чтобы получить удаляемые данные.

Большая проблема, с которой я столкнулся, - это другая таблица, в которой хранится история, она хранит ее с учетной записью, соответствующей таблице c1, но есть также recid, который уникален для каждой записи. Если я иду, чтобы удалить запись C1, она удаляет все из истории, используя accountno, но если я удаляю одну запись истории, то она удаляется по recid.

Ответы [ 3 ]

4 голосов
/ 02 февраля 2012

Вы не можете получить доступ к полям TEXT, NTEXT или IMAGE из INSERTED или DELETED. Однако вы можете получить к ним доступ из базовой таблицы, присоединившись к INSERTED. Это работает только для INSERT и UPDATE, потому что в DELETE базовая строка больше не существует.

Для достижения того, что вам нужно, в другом триггере скопируйте первичный ключ и столбцы TEXT, NTEXT и IMAGE в боковую таблицу.

Например

create table C1(
   accountNo int identity primary key,
   someColumn nvarchar(10),
   someNtext ntext
)

create table C1_side(
   accountNo int primary key,
   someNtext ntext
)

create trigger trgC1_IU  on C1 AFTER INSERT, UPDATE
as
BEGIN
   -- Ensure side row exists
   insert C1_side(accountNo, someNtext)
   select accountNo from INSERTEd
   where not exists (select 1 from C1_side where C1_side.accountNo = inserted.accountNo)

   -- Copy NTEXT value to side row
   update C1_side
   set someNtext = c1.someNtext
   from C1_side inner join C1 on C1_side.accountNo = C1.accountNo
   inner join INSERTED on INSERTED.accountNo = C1.accountNo
   -- Could improve by checking if the column was updated for efficiency

END

Теперь в вашем триггере DELETE вы можете присоединить DELETED к C1_side, чтобы прочитать предыдущее значение столбца ntext. Обратите внимание, что вам придется заполнить начальные значения для вашей боковой таблицы, для строк, которые уже существуют в C1.

3 голосов
/ 01 февраля 2012

Прекратить использование ntext и изображения: они устарели . Вместо этого используйте nvarchar (max) и varbinary (max). Они действуют как обычные типы данных, в отличие от устаревших.

0 голосов
/ 08 февраля 2012

Я обнаружил, что даже если вы удалите несколько строк одновременно, каждая строка все еще помещается во временную таблицу DELETED во время выполнения запроса, поэтому мой триггер затем просматривает каждую запись и сопоставляет ее с recid (который уникален для каждого строка) и удаляет / перемещает оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...