Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有多个条件的MS SQL更新表_Sql_Sql Server_Sql Update - Fatal编程技术网

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

具有多个条件的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 我想创

阅读这个网站已经有一段时间了,现在问我的第一个问题

我正在使用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年,我想,目前还没有用


这将在存储过程中,并在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)