我正在努力调查什么时候&为什么在SQL 2005数据库中删除某些行。我已经开始构建一个触发器,以便在删除行时记录一些信息。
从某个表中删除行时,我的触发器被激活。我将其设置为在发生删除时在另一个日志记录表中记录时间戳。我还想记录已删除的数据,但是不想为每个字段和值编写代码而烦恼。
我知道数据被删除后,可以(暂时)在SQL Server的“已删除”表中看到。所以在删除之后,我可以“SELECT * FROM Deleted”并查看数据。我想获取该表的内容,并将其转换为一个大文本blob,我可以将其保存到我的日志表中的TEXT字段中。
所以...简单来说,有没有办法可以将一行或多行的记录集转换为单个字符串变量?在我的触发器中的所有SQL命令中?如果我可以包含列名,则可以获得奖励。
由于
答案 0 :(得分:1)
在触发器工作时,我会远离任何会运行太久的东西。这包括一些查询只是为了确定静态表格布局(因为你不想自己编写代码),所以你可以构建一个字符串。
我一直都在做这类事情,但主要是使用存储过程参数。我在我使用的模板中有大部分内容。
创建此函数,将在引号内显示列或显示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-在列名称上拖动一个方块,并复制此列基于选择。
返回到您的代码并ALT-Click-在insert语句左栏中的整个“ColumnName ...”值上拖动一个方块并粘贴。如果您选择了列,它将仅替换列,并保持代码左右不变。对插入右侧的“ColumnName ...”值执行相同的操作,现在您有一个INSERT,它将构建您想要的数据,但不会在触发器中浪费太多时间。