具有多个条件的MS SQL更新表

时间:2011-06-23 14:00:42

标签: sql sql-server sql-update

一直在阅读这个网站寻求答案,现在问我的第一个问题!

我正在使用SQL Server

我有两张桌子, ABC ABC_Temp

在进入ABC之前,内容先插入 ABC_Temp 。 表 ABC ABC_Temp 具有相同的列,但 ABC_Temp 有一个名为LastUpdatedDate的额外列,其中包含上次更新的日期。由于 ABC_Temp 可以包含多个相同记录,因此它具有项目编号和上次更新日期的复合键。

列是:ItemNo |价格|数量和 ABC_Temp 有一个额外的列:LastUpdatedDate

我想创建一个遵循以下条件的语句:

  1. 检查 ABC 的每个属性是否与具有相同键的记录的 ABC_Temp 的值不同,如果是,则执行更新(即使只有一个属性)不同,所有其他属性也可以更新)
  2. 只更新需要更改的内容,如果记录相同,则不会更新。
  3. 由于某个项目在 ABC_Temp 中可以有多个记录,因此我只希望将最新更新的记录更新为 ABC
  4. 我目前正在使用2005年(我认为,目前不在工作中)。

    这将在存储过程中,并在VBscript计划任务内部调用。所以我相信这是一次性的事情。此外,我不是要同步这两个表,因为ABC_Temp的内容只包含通过BCP从文本文件批量插入的新记录。为了上下文,这将与插入存储过程结合使用,以检查是否存在记录。

2 个答案:

答案 0 :(得分:2)

UPDATE
    ABC
SET
    price = T1.price,
    qty = T1.qty
FROM
    ABC
INNER JOIN ABC_Temp T1 ON
    T1.item_no = ABC.item_no
LEFT OUTER JOIN ABC_Temp T2 ON
    T2.item_no = T1.item_no AND
    T2.last_updated_date > T1.last_updated_date
WHERE
    T2.item_no IS NULL AND
    (
        T1.price <> ABC.price OR
        T1.qty <> ABC.qty
    )

如果priceqty列中有NULL值,那么您需要考虑到这一点。在这种情况下,我可能会将不等式语句更改为:

COALESCE(T1.price, -1) <> COALESCE(ABC.price, -1)

这假设-1不是数据中的有效值,因此您不必担心它实际出现在那里。

另外,ABC_Temp真的是一个临时表,只需加载足够长的时间就可以将值输入ABC吗?如果没有,那么你在多个地方存储重复数据,这是一个坏主意。第一个问题是,现在您需要这些类型的更新方案。您可能遇到其他问题,例如数据中的不一致等等。

答案 1 :(得分:1)

您可以使用cross apply使用相同的密钥搜索ABC_Temp中的最后一行。使用where子句过滤掉没有差异的行:

update  abc
set     col1 = latest.col1
,       col2 = latest.col2
,       col3 = latest.col3
from    ABC abc
cross apply
        (
        select  top 1 *
        from    ABC_Temp tmp
        where   abc.key = tmp.key
        order by
                tmp.LastUpdatedDate desc
        ) latest
where   abc.col1 <> latest.col1
        or (abc.col2 <> latest.col2
            or (abc.col1 is null and latest.col2 is not null)
            or (abc.col1 is not null and latest.col2 is null))
        or abc.col3 <> latest.col3

在示例中,只有col2可以为空。由于null <> 1不正确,您必须使用is null语法检查涉及null的差异。