T-SQL: How to deny update on one column of a table via trigger?

13,331

Solution 1

CREATE TRIGGER tg_name_me
ON tbl_name
INSTEAD OF UPDATE
AS
IF EXISTS (
   SELECT *
   FROM INSERTED I
   JOIN DELETED D ON D.PK = I.PK AND ISNULL(D.name,I.name+'.') <> ISNULL(I.name,D.name+'.')
)
RAISERROR('Changes to the name in table tbl_name are NOT allowed', 16,1);
GO

Depending on your application framework for accessing the database, a cheaper way to check for changes is Alexander's answer. Some frameworks will generate SQL update statements that include all columns even if they have not changed, such as

UPDATE TBL
   SET name = 'abc', -- unchanged
       col2 = null, -- changed
       ... etc all columns

The UPDATE() function merely checks whether the column is present in the statement, not whether its value has changed. This particular statement will raise an error using UPDATE() but won't if tested using the more elaborate trigger as shown above.

Solution 2

CREATE TRIGGER dbo.yournametrigger ON T_Groups
FOR UPDATE
AS
BEGIN
  IF UPDATE(name)
  BEGIN
    ROLLBACK
    RAISERROR('Changes column name not allowed', 16, 1);
  END
  ELSE
  BEGIN
  --possible update that doesn't change the groupname
  END
END
Share:
13,331
Stefan Steiger
Author by

Stefan Steiger

I'm an avid HTTP-header-reader, github-user and a few more minor things like BusinessIntelligence &amp; Web Software Developer Technologies I work with: Microsoft Reporting- &amp; Analysis Service (2005-2016), ASP.NET, ASP.NET MVC, .NET Core, ADO.NET, JSON, XML, SOAP, Thrift ActiveDirectory, OAuth, MS Federated Login XHTML5, JavaScript (jQuery must die), ReverseAJAX/WebSockets, WebGL, CSS3 C#, .NET/mono, plain old C, and occasional C++ or Java and a little Bash-Scripts, Python and PHP5 I have a rather broad experience with the following relational SQL databases T-SQL PL/PGsql including CLR / extended stored procedures/functions Occasionally, I also work with MySQL/MariaDB Firebird/Interbase Oracle 10g+ SqLite Access I develop Enterprise Web-Applications (.NET 2.0 &amp; 4.5) and interface to systems like LDAP/AD (ActiveDirectory) WebServices (including WCF, SOAP and Thrift) MS Federated Login OAuth DropBox XML &amp; JSON data-stores DWG/SVG imaging for architecture In my spare-time, I'm a Linux-Server-Enthusiast (I have my own Web &amp; DNS server) and reverse-engineer with interest in IDS Systems (IntrusionDetection), WireShark, IDA Pro Advanced, GDB, libPCAP. - Studied Theoretical Physics at the Swiss Federal Institute of Technology (ETHZ).

Updated on June 12, 2022

Comments

  • Stefan Steiger
    Stefan Steiger almost 2 years

    Question:
    In our SQL-Server 2005 database, we have a table T_Groups.
    T_Groups has, amongst other things, the fields ID (PK) and Name.

    Now some idiot in our company used the name as key in a mapping table...
    Which means now one may not alter a group name, because if one does, the mapping is gone...
    Now, until this is resolved, I need to add a restriction to T_Groups, so one can't update the group's name.
    Note that insert should still be possible, and an update that doesn't change the groupname should also be possible.

    Also note that the user of the application & the developers have both dbo and sysadmin rights, so REVOKE/DENY won't work.

    How can I do this with a trigger ?