substring(column_update(),1,1)也可以对那一列更新进行判断!

解决方案 »

  1.   

    create trigger trigger_name on tablename
    for update
    as
    if update(column)
    beginselect getdate()end
      

  2.   

    这样都需要很多的判断的,效率并不一定好,有没有其他的办法
    COLUMNS_UPDATED()可以不
    但是这个值怎么好象十分难以判断是哪个字段
    哪位可否详细给说说
    谢谢
      

  3.   

    IF (COLUMNS_UPDATED()) 测试是否插入或更新了提及的列,仅用于 INSERT 或 UPDATE 触发器中。COLUMNS_UPDATED 返回 varbinary 位模式,表示插入或更新了表中的哪些列。COLUMNS_UPDATED 函数以从左到右的顺序返回位,最左边的为最不重要的位。最左边的位表示表中的第一列;向右的下一位表示第二列,依此类推。如果在表上创建的触发器包含 8 列以上,则 COLUMNS_UPDATED 返回多个字节,最左边的为最不重要的字节。在 INSERT 操作中 COLUMNS_UPDATED 将对所有列返回 TRUE 值,因为这些列插入了显式值或隐性 (NULL) 值。可以在触发器主体中的任意位置使用 COLUMNS_UPDATED。bitwise_operator是用于比较运算的位运算符。updated_bitmask是整型位掩码,表示实际更新或插入的列。例如,表 t1 包含列 C1、C2、C3、C4 和 C5。假定表 t1 上有 UPDATE 触发器,若要检查列 C2、C3 和 C4 是否都有更新,指定值 14;若要检查是否只有列 C2 有更新,指定值 2。comparison_operator是比较运算符。使用等号 (=) 检查 updated_bitmask 中指定的所有列是否都实际进行了更新。使用大于号 (>) 检查 updated_bitmask 中指定的任一列或某些列是否已更新。column_bitmask是要检查的列的整型位掩码,用来检查是否已更新或插入了这些列。
    E. 使用 COLUMNS_UPDATED
    下例创建两个表:一个 employeeData 表和一个 auditEmployeeData 表。人力资源部的成员可以修改 employeeData 表,该表包含敏感的雇员薪水信息。如果更改了雇员的社会保险号码 (SSN)、年薪或银行帐户,则生成审核记录并插入到 auditEmployeeData 审核表。通过使用 COLUMNS_UPDATED() 功能,可以快速测试对这些包含敏感雇员信息的列所做的更改。只有在试图检测对表中的前 8 列所做的更改时,COLUMNS_UPDATED() 才起作用。USE pubs
    IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
       WHERE TABLE_NAME = 'employeeData')
       DROP TABLE employeeData
    IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
       WHERE TABLE_NAME = 'auditEmployeeData')
       DROP TABLE auditEmployeeData
    GO
    CREATE TABLE employeeData (
       emp_id int NOT NULL,
       emp_bankAccountNumber char (10) NOT NULL,
       emp_salary int NOT NULL,
       emp_SSN char (11) NOT NULL,
       emp_lname nchar (32) NOT NULL,
       emp_fname nchar (32) NOT NULL,
       emp_manager int NOT NULL
       )
    GO
    CREATE TABLE auditEmployeeData (
       audit_log_id uniqueidentifier DEFAULT NEWID(),
       audit_log_type char (3) NOT NULL,
       audit_emp_id int NOT NULL,
       audit_emp_bankAccountNumber char (10) NULL,
       audit_emp_salary int NULL,
       audit_emp_SSN char (11) NULL,
       audit_user sysname DEFAULT SUSER_SNAME(),
       audit_changed datetime DEFAULT GETDATE()
       )
    GO
    CREATE TRIGGER updEmployeeData 
    ON employeeData 
    FOR update AS
    /*Check whether columns 2, 3 or 4 has been updated. If any or all of columns 2, 3 or 4 have been changed, create an audit record. The bitmask is: power(2,(2-1))+power(2,(3-1))+power(2,(4-1)) = 14. To check if all columns 2, 3, and 4 are updated, use = 14 in place of >0 (below).*/   IF (COLUMNS_UPDATED() & 14) > 0
    /*Use IF (COLUMNS_UPDATED() & 14) = 14 to see if all of columns 2, 3, and 4 are updated.*/
          BEGIN
    -- Audit OLD record.
          INSERT INTO auditEmployeeData
             (audit_log_type,
             audit_emp_id,
             audit_emp_bankAccountNumber,
             audit_emp_salary,
             audit_emp_SSN)
             SELECT 'OLD', 
                del.emp_id,
                del.emp_bankAccountNumber,
                del.emp_salary,
                del.emp_SSN
             FROM deleted del-- Audit NEW record.
          INSERT INTO auditEmployeeData
             (audit_log_type,
             audit_emp_id,
             audit_emp_bankAccountNumber,
             audit_emp_salary,
             audit_emp_SSN)
             SELECT 'NEW',
                ins.emp_id,
                ins.emp_bankAccountNumber,
                ins.emp_salary,
                ins.emp_SSN
             FROM inserted ins
       END
    GO/*Inserting a new employee does not cause the UPDATE trigger to fire.*/
    INSERT INTO employeeData
       VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32)
    GO/*Updating the employee record for employee number 101 to change the salary to 51000 causes the UPDATE trigger to fire and an audit trail to be produced.*/UPDATE employeeData
       SET emp_salary = 51000
       WHERE emp_id = 101
    GO
    SELECT * FROM auditEmployeeData
    GO/*Updating the employee record for employee number 101 to change both the bank account number and social security number (SSN) causes the UPDATE trigger to fire and an audit trail to be produced.*/UPDATE employeeData
       SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
       WHERE emp_id = 101
    GO
    SELECT * FROM auditEmployeeData
    GOF. 使用 COLUMNS_UPDATED 测试 8 列以上
    如果必须测试影响到表中前 8 列以外的列的更新时,必须使用 UBSTRING 函数测试由 COLUMNS_UPDATED 返回的适当的位。下例测试影响 Northwind.dbo.Customers 表中的第 3、第 5 或第 9 列的更新。USE Northwind
    DROP TRIGGER  tr1
    GO
    CREATE TRIGGER tr1 ON Customers
    FOR UPDATE AS
       IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))
          + power(2,(5-1))) 
          AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1)))
          ) 
       PRINT 'Columns 3, 5 and 9 updated'
    GOUPDATE Customers 
       SET ContactName=ContactName,
          Address=Address,
          Country=Country
    GO
      

  4.   

    E. 使用 COLUMNS_UPDATED
    下例创建两个表:一个 employeeData 表和一个 auditEmployeeData 表。人力资源部的成员可以修改 employeeData 表,该表包含敏感的雇员薪水信息。如果更改了雇员的社会保险号码 (SSN)、年薪或银行帐户,则生成审核记录并插入到 auditEmployeeData 审核表。通过使用 COLUMNS_UPDATED() 功能,可以快速测试对这些包含敏感雇员信息的列所做的更改。只有在试图检测对表中的前 8 列所做的更改时,COLUMNS_UPDATED() 才起作用。USE pubs
    IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
       WHERE TABLE_NAME = 'employeeData')
       DROP TABLE employeeData
    IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
       WHERE TABLE_NAME = 'auditEmployeeData')
       DROP TABLE auditEmployeeData
    GO
    CREATE TABLE employeeData (
       emp_id int NOT NULL,
       emp_bankAccountNumber char (10) NOT NULL,
       emp_salary int NOT NULL,
       emp_SSN char (11) NOT NULL,
       emp_lname nchar (32) NOT NULL,
       emp_fname nchar (32) NOT NULL,
       emp_manager int NOT NULL
       )
    GO
    CREATE TABLE auditEmployeeData (
       audit_log_id uniqueidentifier DEFAULT NEWID(),
       audit_log_type char (3) NOT NULL,
       audit_emp_id int NOT NULL,
       audit_emp_bankAccountNumber char (10) NULL,
       audit_emp_salary int NULL,
       audit_emp_SSN char (11) NULL,
       audit_user sysname DEFAULT SUSER_SNAME(),
       audit_changed datetime DEFAULT GETDATE()
       )
    GO
    CREATE TRIGGER updEmployeeData 
    ON employeeData 
    FOR update AS
    /*Check whether columns 2, 3 or 4 has been updated. If any or all of columns 2, 3 or 4 have been changed, create an audit record. The bitmask is: power(2,(2-1))+power(2,(3-1))+power(2,(4-1)) = 14. To check if all columns 2, 3, and 4 are updated, use = 14 in place of >0 (below).*/   IF (COLUMNS_UPDATED() & 14) > 0
    /*Use IF (COLUMNS_UPDATED() & 14) = 14 to see if all of columns 2, 3, and 4 are updated.*/
          BEGIN
    -- Audit OLD record.
          INSERT INTO auditEmployeeData
             (audit_log_type,
             audit_emp_id,
             audit_emp_bankAccountNumber,
             audit_emp_salary,
             audit_emp_SSN)
             SELECT 'OLD', 
                del.emp_id,
                del.emp_bankAccountNumber,
                del.emp_salary,
                del.emp_SSN
             FROM deleted del-- Audit NEW record.
          INSERT INTO auditEmployeeData
             (audit_log_type,
             audit_emp_id,
             audit_emp_bankAccountNumber,
             audit_emp_salary,
             audit_emp_SSN)
             SELECT 'NEW',
                ins.emp_id,
                ins.emp_bankAccountNumber,
                ins.emp_salary,
                ins.emp_SSN
             FROM inserted ins
       END
    GO/*Inserting a new employee does not cause the UPDATE trigger to fire.*/
    INSERT INTO employeeData
       VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32)
    GO/*Updating the employee record for employee number 101 to change the salary to 51000 causes the UPDATE trigger to fire and an audit trail to be produced.*/UPDATE employeeData
       SET emp_salary = 51000
       WHERE emp_id = 101
    GO
    SELECT * FROM auditEmployeeData
    GO/*Updating the employee record for employee number 101 to change both the bank account number and social security number (SSN) causes the UPDATE trigger to fire and an audit trail to be produced.*/UPDATE employeeData
       SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
       WHERE emp_id = 101
    GO
    SELECT * FROM auditEmployeeData
    GOF. 使用 COLUMNS_UPDATED 测试 8 列以上
    如果必须测试影响到表中前 8 列以外的列的更新时,必须使用 UBSTRING 函数测试由 COLUMNS_UPDATED 返回的适当的位。下例测试影响 Northwind.dbo.Customers 表中的第 3、第 5 或第 9 列的更新。USE Northwind
    DROP TRIGGER  tr1
    GO
    CREATE TRIGGER tr1 ON Customers
    FOR UPDATE AS
       IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))
          + power(2,(5-1))) 
          AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1)))
          ) 
       PRINT 'Columns 3, 5 and 9 updated'
    GOUPDATE Customers 
       SET ContactName=ContactName,
          Address=Address,
          Country=Country
    GO