Tuesday, January 8, 2008

Columns_Updated() within a trigger

Happy New Year to everyone. Once someone asked me about what columns are affected by the UPDATE statement. As you probaly know that in SQL Server 2005 we can do that in more elegant way, but for SQL Server 2000 I decided perfrom some testing.

CREATE TABLE Test (c1 INT NOT NULL PRIMARY KEY, c2 CHAR(1),c3 INT)
GO
--Insert some data
INSERT INTO Test VALUES (1,'A',100)
INSERT INTO Test VALUES (2,'B',500)

--Create a trigger
CREATE TRIGGER tr_my_trigger ON Test FOR UPDATE
AS
DECLARE @ColumnID INT
DECLARE @Columns VARCHAR(8000)
SET @Columns = SPACE(0)
SET @ColumnID = 1
WHILE @ColumnID <= (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Test')
BEGIN
IF (SUBSTRING(COLUMNS_UPDATED(),(@ColumnID - 1) / 8 + 1, 1)) &
POWER(2, (@ColumnID - 1) % 8) =
POWER(2, (@ColumnID - 1) % 8)
SET @Columns = @Columns + CAST(@ColumnID AS VARCHAR) + ','
SET @ColumnID = @ColumnID + 1
END
PRINT 'Updated columns are :' + @Columns

---
UPDATE Test SET c2='D',c3=2000 WHERE c1=1
--Updated columns are :2,3
We see that the second and the third column were affected according to the INFORMATION_SCHEMA.COLUMNS ordered by ORDINAL_POSITION (check it out). It is not comfortable to see those numbers , but with a little effort you can get also name of columns from the INFORMATION_SCHEMA.COLUMNS.

I suggest you not to run/use that on the production server as it may hurt performance.

8 comments:

Razvan Socol said...

Here is a faster trigger, which also provides the column names and takes into account the possible gaps in the sequence of ColumnID-s:

CREATE TRIGGER ShowUpdatedColumns ON Test FOR UPDATE
AS
DECLARE @ColumnID int, @Columns nvarchar(4000), @ObjectID int, @LastColumnID int
SET @ObjectID=(SELECT id FROM sysobjects WHERE name='test')
SET @LastColumnID=(SELECT MAX(colid) FROM syscolumns WHERE id=@ObjectID)
SET @ColumnID=1
WHILE @ColumnID<=@LastColumnID BEGIN
IF (SUBSTRING(COLUMNS_UPDATED(),(@ColumnID - 1) / 8 + 1, 1)) &
POWER(2, (@ColumnID - 1) % 8) = POWER(2, (@ColumnID - 1) % 8)
SET @Columns = ISNULL(@Columns+',','') + COL_NAME(@ObjectID,@ColumnID)
SET @ColumnID=@ColumnID+1
END
PRINT 'Updated columns are :' + @Columns

For example, test both triggers on the following table:

CREATE TABLE Test (c1 INT NOT NULL PRIMARY KEY, x int, c2 CHAR(1))
ALTER TABLE Test DROP COLUMN x
ALTER TABLE Test ADD c3 INT

Using the following code:

DECLARE @i int, @t datetime
SET @i=1
SET @t=GETDATE()
WHILE @i<1000 BEGIN
BEGIN TRAN
UPDATE Test SET c2='C', C3=200 WHERE c1=1
UPDATE Test SET c1=10 WHERE c1=1
UPDATE Test SET c1=10,c2='C' WHERE c1=1
ROLLBACK
SET @i=@i+1
END
SELECT DATEDIFF(ms,@t,GETDATE())

Razvan

Uri Dimant said...

Thanks for posting the script Razvan.

satish said...

As part of auditing, we need to capture the old and new values of only changed fields.
As per this script for column-updated(), it gives the columns list that are included in an update statment, but it will not indicate if the value that is being updated is a
actually a changed value or the same value. Refered the scripts of Pop Rivett for this.
Is there any other efficient way to can capture this.

Unknown said...

I would like to thank you for your nicely written post.
Signature:
Jugar juegos de frozen en línea gratis, los nuevos de princesa de Disney juegos frozen - la princesa encantadora y linda. Divertirse frozen!

Unknown said...

Very interesting! Thanks you.
Signature:
download descargar facebook gratis para Android celular and download free descargar facebook apk and descargar facebook gratis , descarga facebook

Unknown said...

What a great online source of information about this topic. you have done great work. keep continue to sharing such kinds of post. keep it up.
Signature:
download free Descargar Whatsapp Para Android and download baixar whatsapp para celular online and descargar whatsapp , baixar whatsapp gratis

Unknown said...

Thanks for sharing this valuable information to our vision. You have posted a trust worthy blog keep sharing.
Signature:
Versión en facebook en español descargar a los países hablan Español: facebook entrar direto agora , facebook en español descargar , facebook entrar direto agora

Unknown said...

Thank you for that information you article
juegosjuegos
juegos de zombies
jogos de friv