【问题标题】:T-SQL - Select records into concatenated text?T-SQL - 将记录选择为连接文本?
【发布时间】:2010-10-19 14:21:59
【问题描述】:

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

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

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

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

谢谢

【问题讨论】:

    标签: sql-server-2005 triggers concatenation


    【解决方案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,它将构建您想要的数据,但不会在触发器中浪费太多时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-18
      • 2011-10-24
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多