【问题标题】:COLUMNS_UPDATED() return different values when ColumnId is the same当 ColumnId 相同时,COLUMNS_UPDATED() 返回不同的值
【发布时间】:2015-12-03 19:24:53
【问题描述】:

我在 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 - 一切正常

但是让我们尝试添加一些列

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 相同。

【问题讨论】:

    标签: sql-server tsql


    【解决方案1】:

    嗯,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)。正确的位掩码是 如果有 24 列或更少,则为 0x140100,如果 32 列或更少,则为 0x14010000 少,等等。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多