0

我需要遍历表上的字段并在其值不等于其默认值时执行某些操作。

我在触发器中,所以我知道表名。然后我使用这个循环遍历每个字段:

select @field = 0, @maxfield = max(ORDINAL_POSITION) from
INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName

while @field < @maxfield
begin
...

然后我可以通过循环在每次迭代中获取字段名称:

select @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @TableName
and ORDINAL_POSITION = @field

我可以获得该列的默认值:

select @ColDefault = SUBSTRING(Column_Default,2,LEN(Column_Default)-2)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE Table_Name = @TableName
AND Column_name = @fieldname

我有我需要的一切,但我看不到如何比较 2。因为我没有将字段名称作为常量,只有在变量中,我看不到如何从 ' 中获取值插入的表(记住我在触发器中),以查看它是否与默认值相同(现在作为 varchar 保存在 @ColDefault 中)。

4

2 回答 2

2

首先,请记住,触发器可以在多个记录同时进入的情况下触发。如果我这样做:

INSERT INTO dbo.MyTableWithTrigger
  SELECT * FROM dbo.MyOtherTable

那么我在 MyTableWithTrigger 上的触发器将需要处理多个记录。“插入”的伪表中将包含不止一条记录。

话虽如此,要比较数据,您可以运行如下 select 语句:

DECLARE @sqlToExec VARCHAR(8000)
SET @sqlToExec = 'SELECT * FROM INSERTED WHERE [' + @fieldname + '] <> ' + @ColDefault
EXEC(sqlToExec)

这将返回插入的伪表中与默认值不匹配的所有行。听起来您想对这些行做一些事情,所以您可能想要做的是在调用 @sqlToExec 字符串之前创建一个临时表,而不是仅仅选择数据,而是将其插入到临时表中。然后,您可以使用这些行来执行您需要的任何异常处理。

一个问题 - 此 T-SQL 仅适用于数字字段。您可能希望为不同类型的字段构建单独的处理。您可能有 varchars、numeric、blob 等,并且您需要不同的方法来比较它们。

于 2009-01-20T11:50:37.593 回答
2

我怀疑你可以使用 and exec 来做到这一点。

但是为什么不只生成一次代码。性能会更好

于 2011-01-17T15:32:45.517 回答