【问题标题】:Create trigger to insert a column value into other column of same table SQL Server 2005创建触发器以将列值插入到同一表 SQL Server 2005 的其他列中
【发布时间】:2013-07-25 12:04:51
【问题描述】:

如何创建触发器以在表中新插入的行的同一表的另一列的值相同的列中插入值。

假设我有如下表

ColumnA | ColumnB

我希望 columnB 值在行插入表或 columnB 值更新后立即插入到 ColumnA 中。但它不应该反之亦然,即将 columnA 值插入 columnB

。以下代码仅处理 INSERT,请帮助我如何处理表的 插入和更新,即当 columnB 值被插入或更新时。

CREATE TRIGGER inserupdate
   ON  triggertestTable
   AFTER INSERT,UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here
    declare @value int

    select @value=columnB from inserted

    update triggertestTable
    set columnA=@value

END
GO

如果像下面这样插入值,这可以正常工作

insert into triggertestTable(columnB) values('xyz')

ColumnB 值被插入到 columnA

ColumnA | ColumnB
  xyz   |  xyz 

但如果其他应用程序在 columnA 中插入值,则两者都会更新 null 值

 insert into triggertestTable(columnA) values('pqr')

现在记录是

ColumnA | ColumnB
  xyz   |  xyz 
  NULL  |  NULL

正确的记录集应该如下所示

  ColumnA   | ColumnB
      xyz   |  xyz 
      pqr   |  NULL

如何解决这个问题。

【问题讨论】:

  • 如果 ColumnB 得到更新,那么 (1) ColumnA 也应该更新,或者 (2) ColumnA 只有在 ColumnB 的旧值和新值不同时才应该更新?如果在两列(ColumnA 和 ColumbB)中都插入值会发生什么?

标签: sql sql-server sql-server-2005 triggers


【解决方案1】:

试试这个触发器(当将值插入 ColumnB 或更新来自 ColumbB 的值时,它会将值从 ColumnB 复制到 ColumnA):

CREATE TRIGGER trgIU_triggertestTable_UpdateColumnAWhenColumnB
   ON  dbo.triggertestTable
   AFTER INSERT,UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    IF UPDATE(ColumnB)
    BEGIN
        UPDATE  dbo.triggertestTable
        SET     ColumnA=i.ColumnB
        FROM    inserted i
        INNER JOIN dbo.triggertestTable t ON i.MyID=t.MyID
        LEFT JOIN deleted d ON i.MyID=d.MyID
        WHERE   d.MyID IS NULL AND i.ColumnB IS NOT NULL -- Row was inserted
        OR      d.MyID IS NOT NULL -- Row was updated
    END
END
GO

我用过这张桌子:

CREATE TABLE dbo.triggertestTable(
    MyID INT IDENTITY(1,1) PRIMARY KEY, -- MyID should be a PRIMARY KEY or a mandatory(NOT NULL) UNIQUE constraint
    ColumnA VARCHAR(100),
    ColumnB VARCHAR(100)
);
GO

【讨论】:

  • 注意:此时,如果一个语句试图在两列中插入数据,那么 ColumnA 将被来自 ColumbB 的值覆盖。这种行为正确吗?
【解决方案2】:

inserted 是一个伪表,可能包含 多个 行。你应该写一些基于集合的东西。比如:

 update triggertestTable
    set columnA=COALESCE(columnA,columnB)
where id in (select id from inserted)

(如果triggertestTable 有一个名为id 的主键列)

上面将columnA 设置为columnB 的值,如果columnA 还没有值,我认为这可能是您正在寻找的值。

【讨论】:

    【解决方案3】:

    在您的触发器中,只有当 ColumnB 不为 NULL 时,您才必须更新 ColumnA。

    使用以下内容:

    CREATE TRIGGER inserupdate
       ON  triggertestTable
       AFTER INSERT,UPDATE
    AS 
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
        -- Insert statements for trigger here
    
        declare @id1 int
    
        select @value=columnB from inserted
    
        if @value is not null
        begin
            update triggertestTable
            set columnA=@value
        end
    END
    GO
    

    【讨论】:

    • 谢谢,如果 Insert() 语句被执行,但如果行 columnB 值被更新,那么所有 columnA 值也被更新为相同的值...
    • 它在插入两个或更多差异之前有效。将值放入 ColumnB:INSERT INTO triggertestTable(columnB) SELECT 'xyz' UNION ALL SELECT 'abc';。好吧,它可以...
    • 这个触发器的主要问题是它假设inserted 表中只有一行。这意味着它还假设 {INSERT|UPDATE} 语句只影响一行。例如,此语句可能会插入许多行:INSERT ... (ColumnB) SELECT ... FROM ...
    【解决方案4】:

    您是否尝试过以下方法:

        update triggertestTable
        set columnA=@value
        where columnB is not NULL
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 2023-03-31
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多