【问题标题】:Compare Two Tables and Insert New Record Even When Any Value Changes比较两个表并在任何值更改时插入新记录
【发布时间】:2021-08-18 18:56:06
【问题描述】:

我是新手,需要帮助。我有两个这两个表,如果有任何值发生更改或出现新记录,我需要比较并插入新行。 表Product 有主键ID

ID  | ProductCode | [ProductType] | [Margin]
005 | A320        | GAS           | 0.05
006 | A110        | DIS           | 0.15
007 | A310        | GAS           | 0.04

还有表ProductHistory

ID  | ProductCode | ProductType | Margin   | Version
006 | A110        | DIS         | 1.01     | 1
005 | A320        | GAS         | 0.05     | 0
006 | A110        | DIS         | 0.15     | 0
007 | A310        | GAS         | 0.04     | 0

ProductHistory 保留表Product 的任何更改的所有记录。每次有任何变化,表ProductHistory中的列[Version]加1。

我正在编写MERGE 语句来检查表Product 中是否有任何新更改,然后在表[ProductHistory] 中插入新行并更新[Version] 编号。

这是我当前的代码

MERGE [ProductHistory] AS t
    USING dbo.[Product] AS s
        ON t.[ID] = s.[ID]   
    WHEN NOT MATCHED BY TARGET THEN
        INSERT ([Id], [ProductCode], [ProductType], [Margin], [Version])
        VALUES (s.[Id], s.[ProductCode], s.[ProductType], s.[Margin], 0)
   WHEN MATCHED
        AND (t.[ProductCode] <> s.[ProductCode] OR
             t.[ProductType] <> s.[ProductType] OR
             t.[Margin] <> s.[Margin])
      THEN 
        UPDATE
          SET [ID] = s.[ID]
              ,[ProductCode] = s.[ProductCode]
              ,[ProductType] = s.[ProductType]
              ,[Margin] = s.[Margin]
              ,[Version] = t.[Version] + 1

到目前为止,我的代码遇到了问题:

  1. 我需要将表Product 中的值与ProductHistory 中的值与最大[版本] 号进行比较(代码中尚未解决)
  2. ID 匹配但值发生变化时,我需要插入新记录并将[Version] 加一。但是这段代码没有做它应该做的事情。

关于如何解决这些帮助的任何帮助或建议!谢谢

【问题讨论】:

  • Sql Server 使用系统版本控制 为您提供开箱即用的功能,无需编写您自己的代码。
  • 这是一个类项目,所以我不能使用这样的内置函数。 @Stu
  • 很公平,在这种情况下,您只需要在 Products 表上添加一个 trigger 即可进行插入和更新。我也不会使用merge 并尝试维护版本号,只需在每次插入或更新的历史记录中插入一行,以获得完整的可见性;我仍然会看看数据库为您做了什么系统版本控制并遵循原则。
  • 我认为您的方法与“历史”的概念不符。在大多数实现中,您记录一行的每个“版本”。在这里,您似乎只跟踪行的“先前”版本。这真的是你的目标吗?这似乎是底层架构实现,但在这种情况下合并不起作用,因为任何更改都会导致将新“版本”插入历史表。
  • @Stu 我可以看到他们只想维护历史的变化,而不是每次更新。

标签: sql sql-server


【解决方案1】:

我的看法。似乎工作正常。

insert into ProductHistory (ID, ProductCode, ProductType, Margin, Version)
select 
    p.ID, 
    p.ProductCode, 
    p.ProductType, 
    p.Margin, 
    case when ph.Version is null then 0 else ph.Version + 1 end as Version
from Product p
left outer join (
    -- Latest version
    select ID, ProductCode, ProductType, Margin, Version
    from (
        select *,
            row_number() over (partition by ID order by Version desc) as rn
        from ProductHistory
    ) ph
    where rn = 1
) ph on p.id = ph.id
where not exists (
    select 1 
    from ProductHistory
    where ph.id = p.id
      and ph.ProductCode = p.ProductCode 
      and ph.ProductType = p.ProductType
      and ph.Margin = p.Margin
);

【讨论】:

  • 感谢您的回答!每当表 Product 发生任何更改时,我都能够创建一个触发器来自动更新表 ProductHistory。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-22
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多