在触发器中工作时,我会远离任何运行时间过长的事情。这包括一些仅用于确定静态表布局的查询(因为您不想自己编写代码),因此您可以构建一个字符串。
我一直在做这类事情,但主要是使用存储过程参数。我使用的模板中有大部分内容。
创建此函数,将在引号内很好地显示列或显示 NULL:
CREATE FUNCTION [dbo].[QuoteNull]
(
@InputStr varchar(8000) --value to pad
)
RETURNS
varchar(8000)
AS
/*
TEST WITH:
----------
PRINT ' dbo.QuoteNull(null) ->'+dbo.QuoteNull(null)+'<-'
PRINT ' dbo.QuoteNull(''apple'') ->'+dbo.QuoteNull('apple')+'<-'
PRINT ' dbo.QuoteNull(123) ->'+dbo.QuoteNull(123)+'<-'
PRINT ' dbo.QuoteNull(GETDATE()) ->'+dbo.QuoteNull(GETDATE())+'<-'
PRINT ' dbo.QuoteNull(GETDATE()) ->'+dbo.QuoteNull(CONVERT(varchar(23),GETDATE(),121))+'<-'
*/
BEGIN
RETURN COALESCE(''''+@InputStr+'''','null')
END
GO
将此粘贴到您的代码中:
INSERT INTO YourLogTable
(xxx,yyy,zzz,ColumnTextValue)
SELECT
xxx,yyy,zzz,'values:'
+' '+RTRIM('ColumnNameInt ')+'='+dbo.QuoteNull( ColumnNameInt )
+', '+RTRIM('ColumnNameVarchar ')+'='+dbo.QuoteNull( ColumnNameVarchar )
+', '+RTRIM('ColumnNameChar ')+'='+dbo.QuoteNull( ColumnNameChar )
+', '+RTRIM('ColumnNameDate ')+'='+dbo.QuoteNull(CONVERT(varchar(23),ColumnNameDate ,121))
FROM DELETED
确保表中的每一列都有一行(如果有更多,请稍后删除多余的行),如果您想详细查看任何日期,请使用上面显示的转换。
运行此查询:
select sc.name
FROM syscolumns sc INNER JOIN sysobjects so ON sc.id = so.id
where UPPER(so.name)=UPPER('YourTableName') order by sc.colorder desc
在 SQL Server Management Studio 中获取输出(在文本输出模式下),然后在列名称上执行 ALT-LEFT_Click-Drag 一个正方形,然后复制此基于列的选择。
返回到您的代码并按住 ALT 键并单击并在插入语句的左列中的完整“ColumnName...”值上拖动一个正方形并粘贴。如果您选择了列,它将仅替换该列,并且左右保持代码不变。对插入右侧的“ColumnName...”值执行相同的操作,您现在有了一个 INSERT,它将构建您想要的数据,但不会在触发器中浪费太多时间。