Я хотел бы знать, какие столбцы были действительно изменены - PullRequest
4 голосов
/ 11 июля 2010

У меня есть триггер после, реализованный в сборке SQLCLR.В нем я хотел бы знать, какие столбцы действительно обновлены (и их значения были изменены).

К сожалению, SqlContext.TriggerContext.IsUpdatedColumn возвращает значение true, даже если значение столбца остается неизменным.Я думаю, это просто потому, что SQL-запрос, подготовленный не очень умным серверным приложением, переписывает все столбцы, даже если некоторые из них не были изменены пользователем.

Вторая проблема - это некоторые изстолбцы имеют тип ntext, поэтому я даже не могу выбрать их из псевдо таблицы INSERTED (MS SQL Server не допускает поля SELECT, которые имеют тип ntext из INSERTED).Вот почему теперь я ВЫБИРАЮ изменил строки с помощью следующего запроса:

SELECT * FROM [dbo].[MyTable] WHERE [id] IN (SELECT [id] FROM INSERTED)

Что мне нужно сделать, чтобы узнать, какие столбцы не только обновляются, но изменяются?

Теперь у меня естьпростая идея: создать еще один триггер ДО и сохранить обновленные строки изнутри.Затем, когда триггер AFTER выполняется, сравните значения столбца.Эта идея - лучшее, что я могу сделать?Если это так, что является лучшим местом для хранения измененных строк между триггерами ДО и ПОСЛЕ?Временная таблица будет удалена до выполнения триггера AFTER, поскольку я закрываю соединение с контекстом (может быть, просто не закрываю?).

1 Ответ

2 голосов
/ 13 июля 2010

ОК, теперь я решил проблему.

Прежде всего, я создал полную копию исходной таблицы (данные + структура):

IF NOT EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'copyTable')
SELECT * INTO copyTable FROM MyTable

Затем,Я сравниваю исходную таблицу с ее копией в начале моего триггера:

SELECT A.* FROM MyTable A, copyTable B WHERE
    A.id IN (SELECT [id] FROM INSERTED) AND
    A.id = B.id AND
    A.{0} <> B.{0}

Замените {0} на нужный вам столбец.Этот столбец является именно тем столбцом, который вы должны знать, обновлен он или нет.В моем случае это определяется динамически, но вы можете статически подсчитать все нужные вам столбцы.

Et voila - вы выбрали только те строки, которые действительно изменились.В конце триггера не забудьте обновить copyTable новыми значениями:

UPDATE copyTable SET
    id = s.id,
    col1 = s.col1,
    ... all columns you'd like to control ...
FROM MyTable s WHERE
    s.id IN (SELECT [id] FROM INSERTED) AND
    copyTable.id = s.id

Возможно, есть лучшее решение, но это тоже работает.

С уважением,

...