Следующие требования и подход / дизайн приняты
Требование:
Необходимо вставить в таблицу истории для обновления любого столбца таблицы, если и только если значение столбца изменилось.
Необходимо ввести старое значение, новое значение и удобное имя столбца для имени столбца SQL (история отображается для пользователя)
Дизайн / Подход:
- Получить обновленные столбцы.
Цикл каждого столбца
а. Динамически создавать запросы для получения значения столбца из вставленной и удаленной таблицы
б. Получить удобное имя столбца из таблицы сопоставления для столбца
с. Вставить в таблицу истории
Проблема: Exec sp_executesql выдает ошибку
Использование Exec sp_executesql, как указано в приведенном ниже коде, для получения значения. Но это не работает
CREATE TRIGGER dbo.InsertArchiveInfoOnUpdate
ON dbo.A
AFTER UPDATE
AS
BEGIN
IF OBJECT_ID('tempdb..#COLUMNVALUES') IS NOT NULL
DROP TABLE #COLUMNVALUES
CREATE TABLE dbo.#COLUMNVALUES
(
ColumnName VARCHAR(50),
Value varchar(MAX)
)
SELECT * INTO #INSERTEDTABLE FROM INSERTED
SELECT * INTO #DELETEDTABLE FROM DELETED
DECLARE @Columns_Updated VARCHAR(max)
DECLARE @ParmDefinition nvarchar(500);
DECLARE @ColumNameVariable VARCHAR(MAX);
DECLARE @COLUMNNAMEVALUEOUTPUT VARCHAR(max);
DECLARE @COLUMNNAMEVALUE VARCHAR(max);
DECLARE @COLUMN VARCHAR(MAX)
SET NOCOUNT ON;
DECLARE @idTable INT
SELECT @idTable = T.id
FROM sysobjects P JOIN sysobjects T ON P.parent_obj = T.id
WHERE P.id = @@procid
SELECT @Columns_Updated = ISNULL(@Columns_Updated + ', ', '') + name
FROM syscolumns
WHERE id = @idTable
AND CONVERT(VARBINARY,REVERSE(COLUMNS_UPDATED())) & POWER(CONVERT(BIGINT, 2), colorder - 1) > 0
DECLARE @COLUMNNAME VARCHAR(max)
DECLARE @OldColumnValue VARCHAR(MAX)
DECLARE @NewColumnValue VARCHAR(MAX)
DECLARE @UserFriendlyName VARCHAR(MAX)
DECLARE @OldColumnValueQuery VARCHAR(MAX)
DECLARE @NewColumnValueQuery VARCHAR(MAX)
DECLARE @MappingValueQuery VARCHAR(MAX)
DECLARE @InsertArchiveInfoValues VARCHAR(MAX)
--This table valued function will return us the column names which were updated
DECLARE UPDATED_COLUMNS CURSOR FOR select value from dbo.fn_split_string_to_column(@Columns_Updated,',')
OPEN UPDATED_COLUMNS
FETCH NEXT FROM UPDATED_COLUMNS INTO @COLUMNNAME
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
print 1
SET @OldColumnValueQuery ='SELECT @OldColumnValue=@COLUMN FROM #DELETEDTABLE'
SET @NewColumnValueQuery ='SELECT @NewColumnValue=' +@COLUMNNAME+' FROM #INSERTEDTABLE'
SET @MappingValueQuery ='SELECT @UserFriendlyName=LABEL_NAME FROM dbo.TABLE_MAPPING WHERE COLUMN_NAME='''+@COLUMNNAME+''''
SET @ParmDefinition = N'@COLUMN VARCHAR(MAX),@OldColumnValue VARCHAR(max) OUTPUT';
EXECUTE sp_executesql @OldColumnValueQuery, @ParmDefinition, @COLUMN = @COLUMNNAME,@OldColumnValue=@COLUMNNAMEVALUE OUTPUT; select @COLUMNNAMEVALUE
--EXEC @NewColumnValueQuery
--EXEC @MappingValueQuery
END TRY
BEGIN CATCH
INSERT INTO COLUMNNAME VALUES(ERROR_MESSAGE())
END CATCH
FETCH NEXT FROM UPDATED_COLUMNS INTO @COLUMNNAME
END
CLOSE UPDATED_COLUMNS
DEALLOCATE UPDATED_COLUMNS
END
IF OBJECT_ID('tempdb..#COLUMNVALUES') IS NOT NULL
DROP TABLE #COLUMNVALUES
GO
Необходимо получить старое и новое значение из вставленных и удаленных таблиц.