SQL Server 更新触发器,仅获取已修改的字段
我知道COLUMNS_UPDATED
,好吧,我需要一些快捷方式(如果有人做过,我已经在做,但如果有人能节省我的时间,我会应用它)
I am aware of COLUMNS_UPDATED
, well I need some quick shortcut (if anyone has made, I am already making one, but if anyone can save my time, I will appriciate it)
我基本上需要一个只有更新的列值的 XML,我需要这个用于复制目的.
I need basicaly an XML of only updated column values, I need this for replication purpose.
SELECT * FROM insert 给我每一列,但我只需要更新的列.
SELECT * FROM inserted gives me each column, but I need only updated ones.
类似于以下...
CREATE TRIGGER DBCustomers_Insert
ON DBCustomers
AFTER UPDATE
AS
BEGIN
DECLARE @sql as NVARCHAR(1024);
SET @sql = 'SELECT ';
I NEED HELP FOR FOLLOWING LINE ...., I can manually write every column, but I need
an automated routin which can work regardless of column specification
for each column, if its modified append $sql = ',' + columnname...
SET @sql = $sql + ' FROM inserted FOR XML RAW';
DECLARE @x as XML;
SET @x = CAST(EXEC(@sql) AS XML);
.. use @x
END
推荐答案
在触发器内部,你可以像这样使用 COLUMNS_UPDATED()
以获得更新的值
Inside the trigger, you can use COLUMNS_UPDATED()
like this in order to get updated value
-- Get the table id of the trigger
--
DECLARE @idTable INT
SELECT @idTable = T.id
FROM sysobjects P JOIN sysobjects T ON P.parent_obj = T.id
WHERE P.id = @@procid
-- Get COLUMNS_UPDATED if update
--
DECLARE @Columns_Updated VARCHAR(50)
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
但是当你有一个超过 62 列的表格时,这段代码会失败.. Arth.Overflow...
But this snipet of code fails when you have a table with more than 62 columns.. Arth.Overflow...
这是处理超过 62 列但仅提供更新列数的最终版本.很容易与'syscolumns'链接以获取名称
Here is the final version which handles more than 62 columns but give only the number of the updated columns. It's easy to link with 'syscolumns' to get the name
DECLARE @Columns_Updated VARCHAR(100)
SET @Columns_Updated = ''
DECLARE @maxByteCU INT
DECLARE @curByteCU INT
SELECT @maxByteCU = DATALENGTH(COLUMNS_UPDATED()),
@curByteCU = 1
WHILE @curByteCU <= @maxByteCU BEGIN
DECLARE @cByte INT
SET @cByte = SUBSTRING(COLUMNS_UPDATED(), @curByteCU, 1)
DECLARE @curBit INT
DECLARE @maxBit INT
SELECT @curBit = 1,
@maxBit = 8
WHILE @curBit <= @maxBit BEGIN
IF CONVERT(BIT, @cByte & POWER(2,@curBit - 1)) <> 0
SET @Columns_Updated = @Columns_Updated + '[' + CONVERT(VARCHAR, 8 * (@curByteCU - 1) + @curBit) + ']'
SET @curBit = @curBit + 1
END
SET @curByteCU = @curByteCU + 1
END
相关文章