当ColumnId相同时,COLUMNS_UPDATED()返回不同的值

时间:2015-12-03 10:47:24

标签: sql-server tsql

我在msdn。

上阅读了关于COLUMNS_UPDATED()的文章

有例子。 我从示例中减少代码。 使用触发器创建表:

CREATE TABLE dbo.employeeData (
   emp_id int NOT NULL PRIMARY KEY,
   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 TRIGGER dbo.updEmployeeData 
ON dbo.employeeData 
AFTER UPDATE AS
    print COLUMNS_UPDATED() 
    print COLUMNS_UPDATED() & 14
GO
INSERT INTO employeeData
VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32);
GO
  1. 首次更新

    UPDATE dbo.employeeData
    SET emp_salary = 51000
    WHERE emp_id = 101;
    

    触发器返回0x04和4 - 一切正常

  2. 第二次更新

    UPDATE dbo.employeeData
    SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
    WHERE emp_id = 101;
    

    触发器返回0x0A和10 - 一切正常

  3. 但我们尝试添加一些列

    CREATE TABLE dbo.employeeData2 (
        emp_id int NOT NULL PRIMARY KEY,
        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,
        trash1 int NULL,
        trash2 int NULL,
        trash3 int NULL,
        trash4 int NULL,
        trash5 int NULL,
        trash6 int NULL,
        trash7 int NULL,
        trash8 int NULL,
        trash9 int NULL,
        trash10 int NULL,
        trash11 int NULL,
        trash12 int NULL,
        trash13 int NULL,
        trash14 int NULL,
        trash15 int NULL,
        trash16 int NULL,
        trash17 int NULL,
        trash18 int NULL,
        trash19 int NULL,
        trash20 int NULL,
        trash21 int NULL,
        trash22 int NULL,
        trash23 int NULL,
        trash24 int NULL,
        trash25 int NULL,
        trash26 int NULL,
        trash27 int NULL,
        trash28 int NULL,
        trash29 int NULL,
        trash30 int NULL,
        trash31 int NULL
       );
    GO
    
    CREATE TRIGGER dbo.updEmployeeData2
    ON dbo.employeeData2
    AFTER UPDATE AS
       print COLUMNS_UPDATED() 
       print COLUMNS_UPDATED() & 14
    GO
    INSERT INTO employeeData2
    (emp_id,emp_bankAccountNumber,emp_salary,emp_SSN,emp_lname,emp_fname,emp_manager)
    VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32);
    GO
    

    现在它在更新时返回false

    UPDATE dbo.employeeData2
    SET emp_salary = 51000
    WHERE emp_id = 101;
    -- return 0x0400000000
    -- return 0
    
    UPDATE dbo.employeeData2
    SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
    WHERE emp_id = 101;
    -- return 0x0A00000000
    -- return 0
    

    问题: 为什么0x04变为0x0400000000而0x0A变为0x0A00000000? ColumnId在两个表中都相同。

1 个答案:

答案 0 :(得分:4)

嗯,msdn在这个问题上并不是很清楚,但是在你要链接的文档中有一个声明,你可以看到当你的表中有超过8列的时候你必须以另一种方式工作。

事实是,当你有超过8列的时候需要使用子字符串,即使你只在前8列上工作

如陈述here,(给出的示例代码与msdn中相同)

  

但是,如果列数超过八列,则COLUMNS_UPDATED()   函数从左到右按顺序返回字节,最少   最重要的字节是最左边的。最左边的字节将包含   有关第1列到第8列的信息,第二个字节将包含   有关第9列到第16列的信息,依此类推。如果有九个   表中的列,您要检查列2,3或4是否具有   更新后,使用的正确位掩码为0x0E00(十进制3584)。

     

由于按位运算符仅适用于32位整数,因此您可以使用   难以检查超过32列的表。正确的   当有16时,检查第3列,第5列和第9列是否已更改的位掩码   列或更少是0x1401(十进制5121)。正确的位掩码是   0x140100如果有24列或更少,0x14010000如果32列或   少了,等等。

     

因此,如果有超过八列,则需要使用   SUBSTRING分别提取字节