如果(插入)第一个表中的值更大,则SQL Server在另一个表中更新值

时间:2015-07-24 02:27:53

标签: sql sql-server triggers sql-server-2008-r2

我有以下表格:(为简洁起见而简化)

  1. 包含列的AppWorkHeader :( ProjectID (FK),ProgPercent,+ 40其他不相关)
  2. AppProjects列:(ProjectID (PK),ProgPercent + 9其他不相关)
  3. 我正在尝试创建一个触发器,插入后,AppWorkHeader表中的ProgPercent值仅在AppProjects表中的ProgPercent值大于现有值时才更新。我可以使用以下内容进行单次插入:

    -- Only works on single row insert
    CREATE TRIGGER [dbo].[AppWorkHeader_project_trigger]
    ON 
    [dbo].[AppWorkHeader]
    AFTER INSERT AS
    IF @@ROWCOUNT = 0
        RETURN
    
    SET NOCOUNT ON
    
    -- Get the current project completion percentage from the AppProjects table
    DECLARE @inserted_projectID int = (SELECT i.ProjectID FROM inserted i)
    DECLARE @current_percent decimal(5,4) = (SELECT ProgPercent FROM AppProjects WHERE ProjectID = @inserted_projectID)
    
    UPDATE AppProjects
    SET ProgPercent = inserted.ProgPercent
    FROM inserted
    WHERE AppProjects.ProjectID = inserted.ProjectID AND inserted.ProgPercent > @current_percent
    

    我可以使用以下代码进行多次插入。但是,我的where子句的大部分内容似乎被忽略了。具有相同ProjectID的多个插入将更新为更低的值。

    -- Multiple row insert
    CREATE TRIGGER [dbo].[AppWorkHeader_project_trigger]
    ON 
    [dbo].[AppWorkHeader]
    AFTER INSERT AS
    
    IF @@ROWCOUNT = 0
        RETURN
    
    SET NOCOUNT ON
    
    UPDATE AppProjects
    SET ProgPercent = inserted.ProgPercent
    FROM inserted
    WHERE AppProjects.ProjectID = inserted.ProjectID AND inserted.ProgPercent > (SELECT ProgPercent FROM AppProjects WHERE ProjectID = (SELECT inserted.ProjectID))
    

    我无法弄清楚如何在不使用变量的情况下获取AppProjects表中的现有值,如果我使用变量,我似乎无法进行多次插入。我哪里错了?

2 个答案:

答案 0 :(得分:1)

对于每个插入的ProjectID,找到最大ProgPercent(如果有多个行插入了相同的ProjectID)。 然后使用旧值将带有新值的表连接到表中。

CREATE TRIGGER [dbo].[AppWorkHeader_project_trigger]
    ON [dbo].[AppWorkHeader]
    AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;

    WITH
    CTE_InsertedProjects
    AS
    (
        SELECT
            inserted.ProjectID
            ,MAX(inserted.ProgPercent) AS MaxProgPercent
        FROM inserted
        GROUP BY inserted.ProjectID
    )
    ,CTE_AllProjects
    AS
    (
        SELECT
            AppProjects.ProjectID
            ,AppProjects.ProgPercent AS OldProgPercent
            ,CTE_InsertedProjects.MaxProgPercent AS NewProgPercent
        FROM
            AppProjects
            INNER JOIN CTE_InsertedProjects ON CTE_InsertedProjects.ProjectID = AppProjects.ProjectID
        WHERE
            CTE_InsertedProjects.MaxProgPercent > AppProjects.ProgPercent
    )
    UPDATE CTE_AllProjects
    SET OldProgPercent = NewProgPercent;

END

答案 1 :(得分:0)

Tring to Update使用JOIN以匹配AppWorkHeader上AppProjects的列ProjectID ..

Update AP
set AP.ProgPercent=AWH.ProgPercent
FROM AppProjects AP Left JOIN AppWorkHeader AWH on  AP.ProjectID=AWH.ProjectID
Where AP.ProgPercent < AWH.ProgPercent

这将只更新AppProjects中ProgPercent小于AppWorkHeader中ProgPercent的那些行