Предыдущий ответ совсем не помог, но вот что я нашел для этой ситуации.Триггер передаст 4 строки XML.Первая содержит информацию о столбце, следующие две - это содержимое XML временных таблиц INSERTED и DELETED, а последняя - мета-строку (имя схемы, имя таблицы, обновленное пользователем, отметка времени и т. Д.).* Вот как выглядит XML-код столбца:
DECLARE @ColNames XML
DECLARE @ColumnTypeInfo TABLE (
column_name varchar(100),
data_type varchar(100))
INSERT INTO @ColumnTypeInfo (column_name,data_type)
(
SELECT column_name 'column_name',
CASE WHEN
DATA_TYPE = 'datetime' OR DATA_TYPE = 'int' OR DATA_TYPE = 'bit' OR
DATA_TYPE = 'uniqueidentifier' OR DATA_TYPE = 'sql_variant'
THEN DATA_TYPE ELSE
CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NOT NULL THEN
data_type + '(' +
CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10))
+ ')'
ELSE
CASE WHEN NUMERIC_PRECISION IS NOT NULL AND NUMERIC_SCALE IS NOT NULL THEN
data_type + '(' +
CAST(NUMERIC_PRECISION AS VARCHAR(10))
+ ',' +
CAST(NUMERIC_SCALE AS VARCHAR(10))
+ ')'
ELSE
DATA_TYPE
END
END
END 'data_type'
FROM information_schema.columns WHERE table_name = 'tbl_ActivityPart'
)
SET @ColNames = (
SELECT * FROM @ColumnTypeInfo
FOR XML PATH ('Column'), ROOT('ColumnDef')
)
@ ColNames передается в очередь сообщений.
Это основа для процедуры, обрабатывающей сообщения в очереди:
WHILE @cnt <= @totCnt BEGIN
SET @CurrentCol = CAST(@ColNames.query('for $b in /ColumnDef/Column[position()=sql:variable("@cnt")]/column_name return ($b)') AS VARCHAR(MAX))
SET @CurrentCol = REPLACE(REPLACE(@CurrentCol, '<column_name>', ''), '</column_name>', '')
SET @DataType = CAST(@ColNames.query('for $b in /ColumnDef/Column[position()=sql:variable("@cnt")]/data_type return ($b)') AS VARCHAR(MAX))
SET @DataType = REPLACE(REPLACE(@DataType, '<data_type>', ''), '</data_type>', '')
SET @updateQuery = '/Update/Scheme.TableName/'+@CurrentCol
SET @SQL = 'SELECT @TmpXML = @UpdatedXML.query(''' + @updateQuery + ''')'
EXEC sp_executesql @SQL, N'@UpdatedXML xml, @TmpXML XML output', @UpdatedXML, @TmpXML output
SET @childUpdate = @TmpXML
SET @NewValue = REPLACE(REPLACE(CAST(@childUpdate AS VARCHAR(8000)), '<'+@CurrentCol+'>', ''), '</'+@CurrentCol+'>', '')
IF (CHARINDEX('xsi:nil="true"', CONVERT(VARCHAR(8000), @NewValue)) <> 0) BEGIN
SET @NewValue = NULL
END
SET @deleteQuery = '/Delete/Scheme.TableName/'+@CurrentCol
SET @SQL = 'SELECT @TmpXML = @DeletedXML.query(''' + @deleteQuery + ''')'
EXEC sp_executesql @SQL, N'@DeletedXML xml, @TmpXML XML output', @DeletedXML, @TmpXML output
SET @childDelete = @TmpXML
SET @OldValue = REPLACE(REPLACE(CAST(@childDelete AS VARCHAR(8000)), '<'+@CurrentCol+'>', ''), '</'+@CurrentCol+'>', '')
IF (CHARINDEX('xsi:nil="true"', CONVERT(VARCHAR(8000), @OldValue)) <> 0) BEGIN
SET @OldValue = NULL
END
IF @NewValue <> @OldValue BEGIN
INSERT INTO @Changes (SchemaName, TableName, FieldName, DTS,
[uID], OldValue, NewValue, ValueDataType, [User])
SELECT @Schema, @TableName, @CurrentCol, @TimeStamp,
CONVERT(UNIQUEIDENTIFIER, @CurrentUID), @OldValue, @NewValue, @DataType, @UpdateUserID
END
-- **********************************************************************************************************
SELECT @cnt = @cnt + 1
END
Содержимое @Changes затем вставляется в постоянную таблицу (которая теперь находится на томе диска, отдельном от остальных таблиц в этой базе данных).