TSQL:使用触发器中的更新指定的非布尔类型错误

时间:2011-08-09 15:32:00

标签: sql-server tsql sql-server-2008 triggers

我正在尝试在触发器中使用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 个答案:

答案 0 :(得分:2)

如果您只想记录触发器中各列的更改,则可以尝试进行隐藏,可能与完全连接一起使用。我们的想法是,您将inserteddeleted同时取消,然后将它们连接到表的键和包含不透明名称的列,过滤掉值相同的行。

以下是该方法的示例说明。

首先,表定义:

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

当然,设置已经有所简化。特别是,要记录的所有主表的列都是相同的类型,因此不需要将数据转换为某种泛型类型以包含各种类型的数据。但也许这正是你所需要的。如果没有,我相信这可以为实施最终解决方案提供良好的开端。