TSQL: ошибка не-логического типа при обновлении в триггере - PullRequest
1 голос
/ 09 августа 2011

Я пытаюсь использовать функцию обновления в T-sql в триггере, чтобы проверить, был ли столбец изменен или нет.Вот что я делаю:

declare column_name cursor for select name from sys.columns where object_id = object_id(N'tblKit')
open column_name

fetch column_name into @colname
while (@@Fetch_status=0)
begin
if(Update(@colname))

Я получаю сообщение об ошибке, в котором говорится, что не булев тип указан в тех случаях, когда ожидается условиеЭто синтаксис, используемый на форуме msdn.Так что-то не так с этим?

Я использую Microsoft SQL Server 2008 с Management Studio

1 Ответ

2 голосов
/ 22 августа 2011

Если вы просто хотите регистрировать изменения отдельных столбцов в вашем триггере, вы можете попробовать отменить поворот, возможно, в сочетании с полным объединением. Идея состоит в том, что вы отключаете как inserted, так и deleted, а затем соединяете их по ключу таблицы и столбцу, содержащему неповернутые имена, отфильтровывая строки с одинаковыми значениями.

Вот пример иллюстрации метода.

Во-первых, определения таблиц:

CREATE TABLE TestTable (
  ID int IDENTITY PRIMARY KEY,
  Attr1 int,
  Attr2 int,
  Attr3 int
);

CREATE TABLE TestTableLog (
  ID int IDENTITY PRIMARY KEY,
  TableID int,
  AttrName sysname,
  OldValue int,
  NewValue int,
  Timestamp datetime DEFAULT GETDATE()
);

Далее, триггер для регистрации изменений. Этот перехватит все операции: вставка, обновление и удаление:

CREATE TRIGGER trTestTable ON TestTable
AFTER INSERT, UPDATE, DELETE
AS BEGIN
  WITH inserted_unpivot AS (
    SELECT
      ID,
      AttrName,
      Value
    FROM inserted i
    UNPIVOT (Value FOR AttrName IN (Attr1, Attr2, Attr3)) u
  ),
  deleted_unpivot AS (
    SELECT
      ID,
      AttrName,
      Value
    FROM deleted d
    UNPIVOT (Value FOR AttrName IN (Attr1, Attr2, Attr3)) u
  )
  INSERT INTO TestTableLog (TableID, AttrName, OldValue, NewValue)
  SELECT
    ISNULL(i.ID, d.ID),
    ISNULL(i.AttrName, d.AttrName),
    d.Value,
    i.Value
  FROM inserted_unpivot i
    FULL JOIN deleted_unpivot d
      ON i.ID = d.ID AND i.AttrName = d.AttrName
  WHERE CASE i.Value WHEN d.Value THEN 0 ELSE 1 END = 1
END

Теперь давайте заполним TestTable некоторыми данными:

WHILE (SELECT COUNT(*) FROM TestTable) < 15
  INSERT INTO TestTable
  SELECT RAND() * 1000, RAND() * 1000, RAND() * 1000
;

Вот его содержимое до последующих изменений:

ID          Attr1       Attr2       Attr3
----------- ----------- ----------- -----------
1           820         338         831
2           795         881         453
3           228         430         719
4           36          236         105
5           246         115         649
6           488         657         438
7           990         360         15
8           668         978         724
9           872         385         562
10          460         396         462
11          62          599         630
12          145         815         439
13          595         7           54
14          587         85          655
15          80          606         407

А теперь давайте внесем некоторые изменения в содержание:

UPDATE TestTable SET Attr2 = 35 WHERE ID = 3;
UPDATE TestTable SET Attr3 = 0 WHERE ID BETWEEN 6 AND 10;
INSERT INTO TestTable VALUES (1, 1, 1);
DELETE FROM TestTable WHERE ID = 14;

Вот что мы получили в TestTable впоследствии:

ID          Attr1       Attr2       Attr3
----------- ----------- ----------- -----------
1           820         338         831
2           795         881         453
3           228         35          719
4           36          236         105
5           246         115         649
6           488         657         0
7           990         360         0
8           668         978         0
9           872         385         0
10          460         396         0
11          62          599         630
12          145         815         439
13          595         7           54
15          80          606         407
16          1           1           1

И это то, что было зарегистрировано:

ID          TableID     AttrName   OldValue    NewValue    Timestamp
----------- ----------- ----------- ----------- ----------- -----------------------
1           3           Attr2       430         35          2011-08-22 20:12:19.217
2           10          Attr3       462         0           2011-08-22 20:12:19.227
3           9           Attr3       562         0           2011-08-22 20:12:19.227
4           8           Attr3       724         0           2011-08-22 20:12:19.227
5           7           Attr3       15          0           2011-08-22 20:12:19.227
6           6           Attr3       438         0           2011-08-22 20:12:19.227
7           16          Attr1       NULL        1           2011-08-22 20:12:19.227
8           16          Attr3       NULL        1           2011-08-22 20:12:19.227
9           16          Attr2       NULL        1           2011-08-22 20:12:19.227
10          14          Attr1       587         NULL        2011-08-22 20:12:19.230
11          14          Attr2       85          NULL        2011-08-22 20:12:19.230
12          14          Attr3       655         NULL        2011-08-22 20:12:19.230

Настройка, конечно, была несколько упрощена. В частности, все столбцы основной таблицы, которые должны регистрироваться, относятся к одному и тому же типу, поэтому нет необходимости преобразовывать данные в какой-либо универсальный тип для охвата различных типов данных. Но, может быть, это именно то, что вам нужно. А если нет, я считаю, что это может послужить хорошим началом для реализации окончательного решения.

...