Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何知道sql server行中有任何更改?_Sql_Sql Server_Sql Server 2008_Tsql - Fatal编程技术网

如何知道sql server行中有任何更改?

如何知道sql server行中有任何更改?,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我有这样的数据 DeptId DeptName DeptHeadId DeptBudget ---------------------------------------------- 1 HR 1 100000 2 HR-1 2 200000 3 HR-2 5 300000 您是否知道,在特定的部门ID上,任何

我有这样的数据

DeptId    DeptName    DeptHeadId    DeptBudget
----------------------------------------------
1         HR          1             100000
2         HR-1        2             200000
3         HR-2        5             300000
您是否知道,在特定的
部门ID
上,任何列的值都已更改?(不想使用时间戳)


感谢

SQL Server 2008及更高版本支持更改跟踪。我自己没有使用过它,但我相信它不需要使用时间戳字段就可以满足您的需要。请参阅。

您可以使用更新后触发器并使用IF UPDATE指定列,如下所示:

    ....
    AFTER UPDATE
    AS 
    BEGIN

    IF ( UPDATE (DeptName) OR UPDATE (DeptBudget) )
    ....
样本表和数据

CREATE TABLE mytable(DeptId int identity(1,1), 
    DeptName varchar(100),DeptHeadId int, DeptBudget int, HasBeenUpdated bit)

INSERT mytable(DeptName,DeptHeadId, DeptBudget)
values('HR',  1,100000),
      ('HR-1',2,200000),
      ('HR-2',5,300000)

go
触发器语法,这不会对HasBeenUpdated列中的更改作出反应,如果某行“更改”为当前值,则不会注册为已更改的行:

CREATE TRIGGER mytable_trg1
ON mytable
INSTEAD OF UPDATE 
AS
MERGE mytable t1
USING
INSERTED t2
ON t1.DeptId = t2.DeptId
WHEN matched THEN
UPDATE 
SET DeptName = t2.DeptName,
    DeptHeadId=t2.DeptHeadId, 
    DeptBudget=t2.DeptBudget, HasBeenUpdated = 
    CASE WHEN EXISTS
      (SELECT t1.DeptName, t1.DeptHeadId, t1.DeptBudget
       EXCEPT 
       SELECT t2.DeptName, t2.DeptHeadId, t2.DeptBudget) 
       THEN 1 ELSE t2.HasBeenUpdated 
    END
;

go
测试触发器:

UPDATE mytable 
SET DeptName = 'HR-0' 
WHERE deptid = 1
结果

SELECT * FROM mytable

DeptId DeptName    DeptHeadId    DeptBudget  HasBeenUpdated
1      HR-0        1             100000      1
2      HR-1        2             200000      NULL
3      HR-2        5             300000      NULL
在下次更新检查之前重置

UPDATE mytable
SET HasBeenUpdated = 0 
WHERE HasBeenUpdated = 1
  • 为已更新行或未更新行添加一列数据类型(位)
  • 在你的桌子上做一个触发器,如下所示

    CREATE TRIGGER dbo.trigforisupdateornot
       ON  dbo.triggertable
       AFTER UPDATE
    AS 
    BEGIN
    if (UPDATE(DeptName) OR
        UPDATE(DeptHeadId) OR   
        UPDATE(DeptBudget))
    Begin
        Update triggertable
        Set IsUpdate = 1
        Where Deptid = (Select deptid From inserted)
    End
    END
    GO
    
    在更新之前执行此查询

    Select *
    From triggertable
    
    以上查询的输出

    DeptId      DeptName       DeptHeadId  DeptBudget  IsUpdate
    ----------- ----------------------------------------- ----------- ----------- --------
    1           HR                1           100000      NULL
    2           HR-1              2           200000      NULL
    3           HR-2              5           300000      NULL
    
    现在执行下面的查询以更新记录

    Update triggertable
    Set deptname = deptname
    where deptid = 1
    
    现在输出将是

    DeptId      DeptName       DeptHeadId  DeptBudget  IsUpdate
    ----------- ----------------------------------------- ----------- ----------- --------
    1           HR                1           100000      1
    2           HR-1              2           200000      NULL
    3           HR-2              5           300000      NULL
    

    其中IsUpdate=1是更新的行。

    您可以将校验和(DeptName、DeptHeadId、DeptBudget)存储在表中,然后将其与当前校验和值进行比较以查看是否匹配。如果不匹配,您知道它已更改,然后执行操作并更新校验和列。

    更新后触发器如何?是否要在更改发生时检测更改?或者了解历史变化(如果是,比较点是什么,我们如何知道?)