Sql Server 2008 R2
我正在开发一个需要从触发器构建更新/插入/删除语句的同步过程。我并不担心插入或删除,我对更新有疑问。
我想/想要做的是比较更新过程中生成的每列的旧值和新值。只有更改的列,我是否要将它们包含在我的同步脚本中。
嗯,经过一些挖掘和测试,我的问题实际上归结为:我正在尝试执行此声明并且它说它不识别'插入'。有没有不同的方法来做到这一点?
Set @sqlText = 'Insert Into ##changedColumns (ColumnName, NewValue, PrimaryKey) Select ''' + @column + ''', i.' + @column + ', i.' + @primaryKeyColumn + ' From inserted i Inner Join deleted d On d.' + @primaryKeyColumn + ' = i.' + @primaryKeyColumn + ' Where i.' + @column + ' <> d.' + @column
Exec(@sqlText)
答案 0 :(得分:1)
由于这是您采取的路线,我将发表评论作为答案
即使你开始工作,你也会在每个触发器中都有一个光标 硬编码触发器将更有效。
答案 1 :(得分:0)
根据之前编辑的问题,我认为这样的事情可能就是你想要的:
-- sample table
CREATE TABLE [tableA]
(
TableAId int identity(1,1) PRIMARY KEY,
Column1 int not null,
Column2 int null,
Column3 varchar(50) null
)
GO
-- procedure to create sync trigger on target table
CREATE PROCEDURE [dbo].[CreateSyncTrigger]
@table_name NVARCHAR(128)
AS
DECLARE @sql NVARCHAR(MAX);
SET @sql = 'CREATE TRIGGER [mySyncTrigger_' + @table_name + '] ON ' + QUOTENAME(@table_name) + '
AFTER UPDATE
AS
' + (
SELECT
CHAR(10) + 'IF UPDATE(' + QUOTENAME([COLUMN_NAME]) + ')
INSERT INTO ##changedColumns([ColumnName], [NewValue], [PrimaryKey])
SELECT ''' + [COLUMN_NAME] + ''', I.' + QUOTENAME([COLUMN_NAME]) + ', I.' + QUOTENAME([pk_column_name]) + '
FROM INSERTED I
INNER JOIN DELETED D
ON I.' + QUOTENAME([pk_column_name]) + ' = D.' + QUOTENAME([pk_column_name]) + '
WHERE I.' + QUOTENAME([COLUMN_NAME]) + ' != D.' + QUOTENAME([COLUMN_NAME]) + CHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS X
CROSS JOIN ( -- get primary key col
SELECT
D.[name] [table_name],
C.[name] [pk_column_name]
FROM sys.indexes A
INNER JOIN sys.index_columns B
ON A.[object_id] = B.[object_id]
AND A.[index_id] = B.[index_id]
INNER JOIN sys.columns C
ON B.[object_id] = C.[object_id]
AND B.[column_id] = C.[column_id]
INNER JOIN sys.tables D
ON C.[object_id] = D.[object_id]
WHERE A.[is_primary_key] = 1
AND D.[name] = @table_name
) Y
WHERE X.[table_name] = @table_name
AND X.[COLUMN_NAME] != Y.[pk_column_name]
FOR XML PATH(''),TYPE
).value('.','NVARCHAR(MAX)');
-- create trigger on target table
EXECUTE sp_executesql @sql;
GO
-- create sample trigger
EXECUTE [CreateSyncTrigger] 'TableA'
GO
-- sample trigger output
CREATE TRIGGER [mySyncTrigger_TableA]
ON [tableA]
AFTER UPDATE
AS
IF UPDATE ([Column1])
INSERT INTO ##changedColumns([ColumnName], [NewValue], [PrimaryKey])
SELECT 'Column1', I.[Column1], I.[TableAId]
FROM INSERTED I
INNER JOIN DELETED D
ON I.[Column1] != D.[Column1]
...
GO
运行该过程将为所提供的表名的每个非主键列创建所需的触发器。