【问题标题】:SQL Server: update values based on ID with out inserting into tableSQL Server:根据 ID 更新值而不插入表
【发布时间】:2019-01-10 10:41:11
【问题描述】:
ALTER TRIGGER MyTrigger 
ON persons 
AFTER INSERT
AS 
    IF EXISTS(SELECT * 
              FROM Persons t 
              INNER JOIN inserted i ON i.LastName <> t.LastName 
                                    OR i.FirstName <> t.FirstName 
                                    OR i.address <> t.address 
                                    OR i.City <> t.City 
                                    AND i.PersonID = t.PersonID) 
    BEGIN
        UPDATE p 
        SET p.LastName = i.LastName, 
            p.FirstName = i.FirstName,
            p.address = i.address,
            p.City = i.City
        FROM persons AS p
        INNER JOIN inserted i ON p.PersonID <> i.PersonID
        WHERE p.PersonID = i.PersonID 
    END

当我尝试使用以前的 id 插入新列时,该行正在更新,这很好。但是也插入了一个我不想要的新行

【问题讨论】:

标签: sql sql-server tsql triggers


【解决方案1】:

我想你正在寻找

CREATE TRIGGER <Trigger Name Here>
ON <Table Name Here>
INSTEAD OF INSERT, UPDATE
AS
  INSERT INTO <Table Name Here>
  SELECT I.*
  FROM INSERTED I INNER JOIN <Table Name Here> T
  ON I.ID <> T.ID; --Insert all rows with the ID does not exists in the table

  UPDATE T
  SET T.FirstName = I.FirstName,
      T.LastName = I.LastName,
      T.Address = I.Address,
      T.City = I.City
  FROM INSERTED I INNER JOIN <Table Name Here> T
  ON T.ID = I.ID --UPDATE all rows with the same ID already exists in the table
  WHERE T.FirstName <> I.FirstName
        AND --OR
        T.LastName <> I.LastName
        AND --OR
        T.Address <> I.Address
        AND --OR
        T.City <> I.City;
  • &lt;Trigger Name Here&gt; 替换为触发器的名称。
  • &lt;Table Name Here&gt; 替换为您的表名。

【讨论】:

    【解决方案2】:

    我认为您应该学习如何使用merge,而不是在触发器中执行此逻辑。但是,您的问题是关于如何使触发器工作。你想要的是一个替换插入的触发器,而不是之后运行。

    您需要在触发器内进行插入。这看起来像:

    ALTER TRIGGER MyTrigger ON persons INSTEAD OF INSERT
    AS 
    BEGIN
        -- Insert person ids that are new
        INSERT INTO persons
            SELECT i.*
            FROM inserted i
            WHERE NOT EXISTS (SELECT 1
                              FROM persons p
                              WHERE i.PersonID = p.PersonID
                             );
    
        -- update existing person ids
        UPDATE p 
            SET p.LastName = i.LastName, 
                p.FirstName = i.FirstName,
                p.address = i.address,
                p.City = i.City
            FROM persons p INNER JOIN
                 inserted i
                 ON p.PersonID = i.PersonID
            WHERE p.LastName <> i.LastName OR 
                  p.FirstName <> i.FirstName OR
                  p.address <> i.address OR
                  p.City <> i.City;
    END;  -- MyTrigger
    

    我保留了您的比较条件,尽管我认为它们不正确。您需要非常小心 NULL 值。如果任何旧值或新值是NULL,则不会出现UPDATE

    【讨论】:

    • 我们在上面的查询中需要INSTEAD OF INSERT, UPDATE 而不是AFTER INSERT
    • @adams 。 . .谢谢。
    【解决方案3】:

    为什么不试试这样的存储过程

     create stored procedure USP_UpsertPerson
    (
        @personId
        @ other inputsinputs
    )
    
    
    AS 
    BEGIN
     IF( @personId IS NOT NULL)
    BEGIN
     ----------- here Update table script With @personId
    END
    ELSE
    BEGIN
       ----------- here Insert table script
    END
    END 
    GO
    

    然后当你想要插入时发送@personId为null,当你想要更新时发送id

    执行速度比查询快,代码易于引用且运行良好

    【讨论】:

      猜你喜欢
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2015-02-06
      • 1970-01-01
      • 2016-06-13
      相关资源
      最近更新 更多