微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

T-SQL:合并插入旧值和新值然后进行更改

如何解决T-SQL:合并插入旧值和新值然后进行更改

这是我第一次使用 T-sql Merge,我一直在尝试使用以下条件编写存储过程:

  1. 如果记录存在,则将 Id、旧值(更新前)和新值插入 Changes 表,然后更新 Affected 中的旧值

  2. 如果记录不存在,则在 Changes 中插入 Id,为旧值和新值留空,然后在 Affected 中插入新记录

  3. 如果记录不匹配,则将 Id、旧值(删除前的值)插入到 Changes 中,并将空作为新值,然后删除记录

这是我使用的表格

CREATE TABLE Affected
(
    [Id] int IDENTITY(1,1) NOT NULL,[ZoneId] int NOT NULL,[Name] varchar(100) NOT NULL,[Value] varchar(100)
)

CREATE TABLE Changes
(
    [AffectedId] int NOT NULL,[OldValue] varchar(100),[NewValue] varchar(100)
)

这是我的存储过程,它以两个区域 ID 作为输入参数

CREATE PROCEDURE spAffectChanges
    @ZoneId1 int,@ZoneId2 int
AS
    IF(@ZoneId1 < 10)
    BEGIN
        ;WITH fromQ AS 
        (
            SELECT disTINCT Name,Value 
            FROM Affected 
            WHERE ZoneId = @ZoneId1 AND Name NOT IN ('aaa','bbb','ccc')
        ),toQ AS
        (
            SELECT disTINCT Name,Value 
            FROM Affected 
            WHERE ZoneId = @ZoneId2 AND Name NOT IN ('aaa','ccc')
        )
        MERGE toQ
        USING fromQ ON (toQ.Name = fromQ.Name)

        WHEN MATCHED AND fromQ.Value<>toQ.Value THEN
            ----first insert
            INSERT INTO Changes (AffectedId,OldValue,NewValue)
            VALUES(toQ.Id,toQ.Value,fromQ.Value)
            ----then update
            UPDATE SET toQ.Value=fromQ.Value

        WHEN NOT MATCHED BY toQ THEN
            ----first insert
            INSERT INTO Changes (AffectedId,'',fromQ.Value)
            ----second insert 
            INSERT (Name,Zone,Value)
            VALUES (fromQ.Name,@ZoneId1,fromQ.Value)

        WHEN NOT MATCHED BY fromQ THEN
            ----first insert
            INSERT INTO Changes (AffectedId,'')
            ----then delete
            DELETE
    END

有没有办法对 Affected 执行插入更改和更新/插入/删除

提前致谢

解决方法

您可以使用 OUTPUT 子句来执行此操作。

注意事项:

  • MERGE 需要一个分号终止符。 ;WITH 很傻,; 不是开始符,它应该放在每个命令的末尾
  • WHEN NOT MATCHED 的选项是 BY SOURCEBY TARGET(这是默认值)
  • 我不太明白您如何在目标上使用 DISTINCT,我认为这是不允许的,也不知道这样做有什么意义。
        WITH fromQ AS 
        (
            SELECT DISTINCT Name,Value 
            FROM Affected 
            WHERE ZoneId = @ZoneId1 AND Name NOT IN ('aaa','bbb','ccc')
        ),toQ AS
        (
            SELECT Name,Value 
            FROM Affected 
            WHERE ZoneId = @ZoneId2 AND Name NOT IN ('aaa','ccc')
        )
        MERGE toQ
        USING fromQ ON (toQ.Name = fromQ.Name)

        WHEN MATCHED AND fromQ.Value <> toQ.Value THEN
            UPDATE
                SET toQ.Value = fromQ.Value

        WHEN NOT MATCHED BY TARGET THEN
            INSERT (Name,Zone,Value)
            VALUES (fromQ.Name,@ZoneId1,fromQ.Value)

        WHEN NOT MATCHED BY SOURCE THEN
            DELETE

        OUTPUT inserted.Id,ISNULL(deleted.Value,''),ISNULL(inserted.Value,'')
            INTO Changes (AffectedId,OldValue,NewValue)
        ;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。