2

我正在尝试调查何时以及为什么在 SQL 2005 数据库中删除某些行。我已经开始构建一个触发器来在删除一行时记录一些信息。

当从某个表中删除行时,我的触发器被激活。我已将其设置为在删除发生时在另一个日志记录表中记录时间戳。我还想记录被删除的数据,但不想为每个字段和值编写代码而烦恼。

我知道当数据被删除时,它可以(暂时)在 SQL Server 的“已删除”表中看到。所以在删除之后,我可以“SELECT * FROM Deleted”并查看数据。我想把这个表的内容变成一个大的文本块,我可以把它保存到我的日志表中的一个文本字段中。

所以......简单来说,有没有一种方法可以获取一个或多个行的记录集并将其转换为单个字符串变量?全部在我的触发器中的 SQL 命令中?如果我可以包含列名,则可以加分。

谢谢

4

1 回答 1

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-Drag 一个正方形,然后复制此基于列的选择。

返回到您的代码并按住 ALT 键并单击并在插入语句的左列中的完整“ColumnName...”值上拖动一个正方形并粘贴。如果您选择了列,它将仅替换该列,并且左右保持代码不变。对插入右侧的“ColumnName...”值执行相同的操作,您现在有了一个 INSERT,它将构建您想要的数据,但不会在触发器中浪费太多时间。

于 2009-04-15T14:05:27.920 回答