From SQL Server 2000, there’s been support for a function called COLUMNS_UPDATED. I haven’t used it much, but I’ve written triggers using it a couple of times, and every time I do that, I’ve forgot how it works. Now, I’m going to put it here on my blog
So, basically, this function returns which fields are actually updated. This can be useful if for instance you want users to be able to update one column, but not the others on a table. Instead of doing:
IF UPDATE(AllowedField)
AND NOT UPDATE(NotAllowedField1)
AND NOT UPDATE(NotAllowedField2)
AND NOT UPDATE(NotAllowedField3)
BEGIN
RAISERROR('You are not allowed to change fields other than: AllowedField', 18, 1)
ROLLBACK TRANSACTION
RETURN
END
The problem with this solution is of course if you add new fields, you’re more or less proper-fucked.
CREATE TABLE test (
NotAllowedField1 NVARCHAR(128),
NotAllowedField2 NVARCHAR(128),
NotAllowedField3 NVARCHAR(128),
AllowedField NVARCHAR(128)
)
GO
INSERT INTO test
(NotAllowedField1, NotAllowedField2, NotAllowedField3, AllowedField)
VALUES
('aaaa', 'aaaa', 'aaaa', 'aaaa')
GO 5
CREATE TRIGGER test_ITrig ON test
AFTER UPDATE
AS
BEGIN
DECLARE @AllowedFieldName AS NVARCHAR(128)
DECLARE @ColumnNumber AS INT
SET @AllowedFieldName = 'AllowedField'
SET @ColumnNumber = (SELECT colid
FROM sys.syscolumns
WHERE id = OBJECT_ID('test')
AND name = @AllowedFieldName)
IF (COLUMNS_UPDATED() ^ POWER(2, ((@ColumnNumber) - 1))) > 0
BEGIN
RAISERROR('You are not allowed to change fields other than: %s',
18, 1, @AllowedFieldName)
ROLLBACK TRANSACTION
RETURN
END
END
GO
-- Not allowed single
UPDATE test
SET NotAllowedField1 = 'bbbb'
-- Not allowed multiple
UPDATE test
SET
AllowedField = 'bbbb',
NotAllowedField2 = 'bbbb',
NotAllowedField3 = 'bbbb'
-- Allowed single
UPDATE test
SET AllowedField = 'bbbb'
-- Clean-up
DROP TRIGGER test_ITrig
GO
DROP TABLE test
GO
Like this:
Like Loading...