【问题标题】:update trigger to update records in another table更新触发器以更新另一个表中的记录
【发布时间】:2015-05-16 09:29:01
【问题描述】:

我有 User_Table

CREATE TABLE [dbo].[User_TB]
  (
    [User_Id] [varchar](15) NOT NULL,
    [User_FullName] [varchar](50) NULL,
    [User_Address] [varchar](150) NULL,
    [User_Gender] [varchar](10) NULL,
    [User_Joindate] [varchar](50) NULL,
    [User_Email] [varchar](50) NULL,
    [User_Branch] [varchar](50) NULL,
    [User_TeamLeader] [varchar](50) NULL,
    [User_Department] [varchar](50) NULL,
    [User_Position] [varchar](50) NULL,
    [TID] [int] NULL
  )

Break_Table

CREATE TABLE [dbo].[Break_TB]
  (
     [Break_Id] [int] IDENTITY(1,1) NOT NULL,
     [User_Id] [varchar](15) NOT NULL,
     [Date] [date] NULL,
     [Break_Time] [int] NULL,
     [Status] [varchar](50) NULL,
     [Late_time] [int] NULL,
     [TL_Id] [varchar](15) NULL,
     [start_Time] [time](7) NULL,
     [end_Time] [time](7) NULL,
 )

日志表

CREATE TABLE [dbo].[Log_TB]
 (
   [User_Id] [varchar](50) NOT NULL,
   [First_Login] [time](0) NULL,
   [Logout] [time](0) NULL,
   [Date] [date] NULL,
   [Working_Hrs] [time](0) NULL,
 )

现在要做的是,每当 User_Table 中的 User_Id 更新时,我想尝试更新另外两个表的 User_Id,

我已经为此编写了触发器

Alter TRIGGER [dbo].[updateUserId] on [dbo].[User_TB]
 FOR Update
 AS 
 declare @Branch_Name varchar(50),
 @User_Id varchar(15) 

 select @User_Id = i.User_Id from inserted i;

 Update Break_TB set User_Id = @User_Id where User_Id = @User_Id;
 Update Log_TB set User_Id = @User_Id where User_Id = @User_Id;

但是

只更新 Break_TB 的记录,不适用于 Log_TB

我不太擅长触发器,如果​​错了请帮助我。

【问题讨论】:

  • 您的触发器有 MAJOR 缺陷,因为您似乎认为它会每行调用一次 - 那是不是 b> 情况。触发器每个语句触发一次,因此如果您的UPDATE 语句影响25 行,您将触发触发器一次,然后Inserted 和@987654327 @ 每个将包含 25 行。您的代码将在这 25 行中选择哪一行? select @User_Id = i.User_Id from inserted i; - 它是不确定的,你得到 一个,任意 行,而你忽略所有其他行。您需要重写触发器以考虑到这一点!
  • 你能告诉我如何解决它@marc_s
  • log_tb中user_id列的数据类型是什么?
  • 另外,您的两个更新语句什么都不做 - 它们将值更新为已经存在的值。
  • 对于 user_Id 在所有表中都是 Varchar@Bohemian

标签: sql sql-server-2008 triggers


【解决方案1】:

您需要这样的东西 - 基于集合的解决方案,考虑到在UPDATE 语句中,您可能会同时更新多行,因此您的触发器还必须处理InsertedDeleted 表中的多行。

CREATE TRIGGER [dbo].[updateUserId] 
ON [dbo].[User_TB]
FOR UPDATE
AS 
    -- update the "Break" table - find the rows based on the *old* User_Id
    -- from the "Deleted" pseudo table, and set it to the *new* User_Id
    -- from the "Inserted" pseudo table
    SET User_Id = i.User_Id 
    FROM Inserted i
    INNER JOIN Deleted d ON i.TID = d.TID
    WHERE
        Break_TB.User_Id = d.User_Id

    -- update the "Log" table - find the rows based on the *old* User_Id
    -- from the "Deleted" pseudo table, and set it to the *new* User_Id
    -- from the "Inserted" pseudo table
    UPDATE Break_TB 
    SET User_Id = i.User_Id 
    FROM Inserted i
    INNER JOIN Deleted d ON i.TID = d.TID
    WHERE
        Break_TB.User_Id = d.User_Id

此代码假定User_TB 表中的TID 列是主键,它在更新期间保持不变(这样我就可以将Deleted 伪表中的“旧”值与更新后的“新”值,存储在Inserted 伪表中)

【讨论】:

  • no @marc_s TID 不是主键,我试图在 UPDATE 之后而不是在插入或删除之后更新这些记录
  • @ChetanBodke:当您执行UPDATE 时,Deleted 表中存在 值,而 值(更新后)存在于Inserted 表中 - 这确实 NOT 意味着您正在执行插入和删除操作 - 这 IS 一个UPDATE !!另外:在这种情况下,User_TB 的主键是什么??
  • User_Id 本身就是主键
  • @ChetanBodke:但这在UPDATE 中发生了变化——这对于主键来说是一个非常糟糕的主意!您应该有一些固定的主键,随着时间的推移不会改变
  • ok .. @marc_s 我会调查一下.. 你现在能帮忙解决当前的问题吗
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多