T-SQL - Выбрать записи в объединенном тексте? - PullRequest
2 голосов
/ 15 апреля 2009

Я пытаюсь выяснить, когда и почему определенные строки удаляются в базе данных SQL 2005. Я начал создавать триггер для регистрации некоторой информации при удалении строки.

Мой триггер активируется при удалении строки (ей) из определенной таблицы. У меня есть его настроить для записи метки времени в другой таблице журналов, когда происходит удаление. Я также хотел бы регистрировать данные, которые были удалены, но предпочел бы не создавать код для каждого поля и значения.

Я знаю, что когда данные удалены, их можно увидеть (временно) в таблице «Удаленные» в SQL Server. Так что сразу после удаления я мог "ВЫБРАТЬ * ОТ УДАЛЕНО" и видеть данные. Я хотел бы взять содержимое этой таблицы и превратить его в один большой текстовый объект, который я могу просто сохранить в поле TEXT в своей таблице журналов.

Итак ... проще говоря, могу ли я взять набор записей из одной или нескольких строк и превратить его в одну строковую переменную? все внутри команд SQL в моем триггере? Бонусные баллы, если я могу включить названия столбцов.

Спасибо

1 Ответ

1 голос
/ 15 апреля 2009

Я бы держался подальше от всего, что работало бы слишком долго при работе в триггере. Это включает в себя некоторый запрос только для определения статического макета таблицы (потому что вы не хотите писать код самостоятельно), чтобы вы могли построить строку.

Я все время так делаю, но в основном с параметрами хранимых процедур. У меня есть большая часть этого в шаблоне, который я использую.

создайте эту функцию, будет красиво отображать столбец в кавычках или показывать 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-Click-Drag перетащите квадрат над полными значениями «ColumnName ...» в левом столбце оператора вставки и вставьте. Если вы сделали выбор столбца, он заменит только столбец и оставит код без изменений слева и справа. Сделайте то же самое для значений «ColumnName ...» в правой части вставки, и теперь у вас есть INSERT, который будет создавать нужные данные, но не будет тратить слишком много времени на триггер.

...