具有多个条件的MS SQL更新表
阅读这个网站已经有一段时间了,现在问我的第一个问题 我正在使用SQL Server 我有两张桌子,ABC和ABC 内容首先插入ABC_Temp,然后再进入ABC。 表ABC和ABC_Temp有相同的列,除了ABC_Temp有一个名为LastUpdateDate的额外列,该列包含上次更新的日期。因为ABC_Temp可以有多条相同的记录,所以它有一个项目编号和上次更新日期的复合键 列为:ItemNo | Price | Qty和ABC|u Temp有一个额外的列:lastUpdateDate 我想创建一个符合以下条件的语句: 检查ABC的每个属性是否与具有相同键的记录的ABC_Temp值不同,如果是,则进行更新,即使只有一个属性不同,也可以更新所有其他属性 只更新那些需要更改的记录,如果记录相同,则不会更新。 由于一个项目在ABC_Temp中可以有多个记录,我只希望最新更新的记录更新到ABC 我现在用的是2005年,我想,目前还没有用具有多个条件的MS SQL更新表,sql,sql-server,sql-update,Sql,Sql Server,Sql Update,阅读这个网站已经有一段时间了,现在问我的第一个问题 我正在使用SQL Server 我有两张桌子,ABC和ABC 内容首先插入ABC_Temp,然后再进入ABC。 表ABC和ABC_Temp有相同的列,除了ABC_Temp有一个名为LastUpdateDate的额外列,该列包含上次更新的日期。因为ABC_Temp可以有多条相同的记录,所以它有一个项目编号和上次更新日期的复合键 列为:ItemNo | Price | Qty和ABC|u Temp有一个额外的列:lastUpdateDate 我想创
这将在存储过程中,并在VBscript计划任务中调用。所以我相信这是一次性的事情。另外,我没有尝试同步这两个表,因为ABC_Temp的内容只包含通过BCP从文本文件批量插入的新记录。出于上下文的考虑,这将与检查记录是否存在的insert stored proc一起使用。您可以使用交叉应用以使用相同的键查找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。由于null 1不是true,因此必须使用is null语法检查涉及null的差异
这假设-1在数据中不是有效值,因此您不必担心它实际出现在那里
另外,ABC_Temp真的是一个临时表,它加载的时间足够长,可以将值输入ABC吗?如果没有,那么您将在多个位置存储重复数据,这是一个坏主意。第一个问题是,现在您需要这些类型的更新场景。您可能会遇到其他问题,如数据不一致等。您使用的是哪个版本的SQL Server?请描述使用场景-这是一次性作业,您希望只同步两个表一次,还是计划按计划执行。或者您希望动态执行此操作—每当将新记录推送到ABC_Temp时,您都需要更新ABC。这将在存储过程中进行,并在VBscript计划任务中调用。所以我相信这是一次性的事情。另外,我没有尝试同步这两个表,因为ABC_Temp的内容只包含通过BCP从文本文件批量插入的新记录。出于上下文的考虑,这将与一个insert stored proc一起使用,该程序检查记录是否存在,并添加一条注释,指出:Wont checking For latest.col2是null吗?如果某些行已经有值,则会将其设置为null?是的,ABC_Temp实际上是一个Temp。在bcp插入表之前,在VBScript开始时删除ABC_Temp中的所有记录。因此,在将记录放入永久表ABC之前,ABC_Temp充当记录的过滤器。明天我也会尝试这种方法,谢谢你的回答!非常感谢,这对我很有用!但我真正不明白的是为什么T2.item_no为NULL?假设T2.item_no为非NULL列,则T2.item_no可以为NULL的唯一方法是如果左侧外部联接未能找到匹配的行。所以,这个查询说的是,只给我那些在T1行之后找不到T2的行。。。或者,T1是最新可能的行。这基本上是做一件不存在的事情的另一种方式
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
)
COALESCE(T1.price, -1) <> COALESCE(ABC.price, -1)