SQL 如果(插入的)第一个 table 中的值更大,则另一个 table 中的服务器更新值

SQL Server update value in another table if value in (inserted) first table is greater

我有以下 tables:(为清楚起见进行了简化)

  1. 带有列的 AppWorkHeader:(ProjectID (FK),ProgPercent,+ 40 个其他不相关)
  2. 具有以下列的 AppProjects:(项目 ID (PK),ProgPercent + 其他 9 个不相关)

我正在尝试创建一个触发器,在插入后,AppWorkHeader table 中的 ProgPercent 值仅在 AppProjects table 中的 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 table 中的现有值,而且如果我使用变量,我似乎无法进行多次插入。我哪里错了?

尝试更新时使用 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 的那些行

对于每个插入的 ProjectID 找到最大值 ProgPercent(如果有几行插入相同的 ProjectID)。 然后将具有新值的 table 加入具有旧值的 table。

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