Sql server 如何仅在任何列与另一个表中的匹配行不同时插入行

Sql server 如何仅在任何列与另一个表中的匹配行不同时插入行,sql-server,tsql,insert,compare,Sql Server,Tsql,Insert,Compare,本质上,我是在收集我们网络上的计算机列表。我想比较我的临时表general中的信息,以便在我的AdscangGeneral表中找到一个特定的计算机名XXXX-XXXX-XXXXX。基本上,我想将general的计算机条目的列与ADScanGeneral中的最新条目进行比较,如果它们在任何地方不同,则将该行作为新条目一般输入ADScanGeneral。否则,如果它们相同,则只需更新该计算机的ADScanGeneral.EntryDate列 我的问题是,如果不进行长时间的循环,我想不出一种方法来比较

本质上,我是在收集我们网络上的计算机列表。我想比较我的临时表general中的信息,以便在我的AdscangGeneral表中找到一个特定的计算机名XXXX-XXXX-XXXXX。基本上,我想将general的计算机条目的列与ADScanGeneral中的最新条目进行比较,如果它们在任何地方不同,则将该行作为新条目一般输入ADScanGeneral。否则,如果它们相同,则只需更新该计算机的ADScanGeneral.EntryDate列

我的问题是,如果不进行长时间的循环,我想不出一种方法来比较单个条目的列general和AdscangGeneral。这在SQL语句中可能吗

我的下表示例:

一般的

Name    Status  lastLogon   LastLogonDate   lastLogonTimestamp  ResolvedIP  Manufacturer    Model   Architecture    TotalPhysicalMemory LastLoggedOnUser    WakeUpType  OperatingSystem OperatingSystemVersion  OperatingSystemArchitecture SystemDrive SerialNumber    SMBIOSBIOSVersion   BIOSVersion CPUName CPUCaption  MaxClockSpeed   LastClockSpeed  NumberOfProcessors  NumberOfCores   NumberOfThreads
XXXX-XXXX-10362 1   2018-02-01 06:37:18 2018-01-27 22:37:03 2018-01-27 22:37:03 10.1.19.7   Dell Inc.   OptiPlex 390    x64-based PC    8481869824  XXXXX\amanda.creathbaum 6   Microsoft Windows 10 Pro    10.1.7601   64-bit  C:  G6WLTR1 A01 DELL   - 6222004    Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz Intel64 Family 6 Model 42 Stepping 7    3101    1581    1   4   4
XXXX-XXXX-10947 0   2018-02-01 06:29:57 2018-02-01 02:09:54 2018-02-01 02:09:54 10.1.19.4                                                                               
XXXX-XXXX-01738 0   2018-02-01 17:58:37 2017-11-13 17:58:37 2017-11-13 17:58:37                                                                                 
ADScanGeneral

Name    Status  lastLogon   LastLogonDate   lastLogonTimestamp  ResolvedIP  Manufacturer    Model   Architecture    TotalPhysicalMemory LastLoggedOnUser    WakeUpType  OperatingSystem OperatingSystemVersion  OperatingSystemArchitecture SystemDrive SerialNumber    SMBIOSBIOSVersion   BIOSVersion CPUName CPUCaption  MaxClockSpeed   LastClockSpeed  NumberOfProcessors  NumberOfCores   NumberOfThreads    EntryDate
XXXX-XXXX-10362 1   2018-02-01 06:37:18 2018-01-27 22:37:03 2018-01-27 22:37:03 10.1.19.7   Dell Inc.   OptiPlex 390    x64-based PC    8481869824  XXXXX\amanda.creathbaum 6   Microsoft Windows 7 Professional    6.1.7601    64-bit  C:  G6WLTR1 A01 DELL   - 6222004    Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz Intel64 Family 6 Model 42 Stepping 7    3101    1581    1   4   4    2018-02-01 06:37:18
XXXX-XXXX-10947 0   2018-02-01 06:29:57 2018-02-01 02:09:54 2018-02-01 02:09:54 10.1.19.4                                                                               2018-02-01 06:37:18
XXXX-XXXX-01738 0   2017-11-13 17:58:37 2017-11-13 17:58:37 2017-11-13 17:58:37                                                                                 2018-02-01 06:37:18
因此,对于第一个条目,操作系统已更改为Windows 10,因此我想将整个条目作为新条目插入AdscangGeneral。第二个条目,没有任何更改,因此我想更新AdscangGeneral中的条目日期。第三个条目有一个更为最新的lastLogon,所以我想把它作为一个新条目添加到AdscangGeneral中

这有意义吗?如果你需要澄清,请询问,我会尽力帮助你。谢谢所有帮忙的人

JoeC建议签出merge命令,但它似乎只匹配在ON条件中指定的2个字段,而我需要它匹配整行。因此,我不确定我是否只是错误地使用了该命令,或者它是否对我不起作用。下面是我提出的合并命令:

MERGE   ADScanGeneral   AS TARGET
USING   #General        AS SOURCE
ON      (TARGET.[Name] = SOURCE.[Name])
WHEN MATCHED THEN
        UPDATE SET EntryDate = getdate()
WHEN NOT MATCHED THEN
        INSERT  (
                    [Name], 
                    [Status], 
                    LastLogon, 
                    LastLogonDate, 
                    LastLogonTimestamp,
                    ResolvedIP, 
                    Manufacturer, 
                    Model, 
                    Architecture, 
                    TotalPhysicalMemory, 
                    LastLoggedOnUser,
                    WakeUpType,
                    OperatingSystem,
                    OperatingSystemVersion,
                    OperatingSystemArchitecture,
                    SystemDirectory,
                    SerialNumber,
                    SMBIOSVersion,
                    BIOSVersion,
                    CPUName,
                    CPUCaption,
                    MaxClockSpeed,
                    NumberOfProcessors,
                    NumberOfThreads,
                    NumberOfCores
                )
        VALUES  (
                    SOURCE.[Name], 
                    SOURCE.[Status], 
                    SOURCE.LastLogon, 
                    SOURCE.LastLogonDate, 
                    SOURCE.LastLogonTimestamp,
                    SOURCE.ResolvedIP, 
                    SOURCE.Manufacturer, 
                    SOURCE.Model, 
                    SOURCE.Architecture, 
                    SOURCE.TotalPhysicalMemory, 
                    SOURCE.LastLoggedOnUser,
                    SOURCE.WakeUpType,
                    SOURCE.OperatingSystem,
                    SOURCE.OperatingSystemVersion,
                    SOURCE.OperatingSystemArchitecture,
                    SOURCE.SystemDirectory,
                    SOURCE.SerialNumber,
                    SOURCE.SMBIOSVersion,
                    SOURCE.BIOSVersion,
                    SOURCE.CPUName,
                    SOURCE.CPUCaption,
                    SOURCE.MaxClockSpeed,
                    SOURCE.NumberOfProcessors,
                    SOURCE.NumberOfCores,
                    SOURCE.NumberOfThreads
                );

实现这一点的一种方法是使用跟踪已插入的名称,并在过滤后在第二个查询中执行更新以删除已插入的名称

可能有更好的方法来检查更改,但下面的代码应该可以工作

declare @inserted_names table ([Name] varchar(255));

-- insert into ADScanGeneral any records from #general with changes, or any
-- name that is not present in ADScanGeneral
-- the names of the inserted record are stored to a table variable
insert into ADScanGeneral
output inserted.[Name] into @inserted_names ([Name])
select
    c.*, GetDate() as EntryDate
from
    ADScanGeneral as a
inner join
    (
        select
            a.[Name], max(a.EntryDate) as MaxEntryDate
        from
            ADScanGeneral as a
        group by
            a.[Name]
    ) as b
    on
        a.[Name] = b.[Name]
        and
        a.EntryDate = b.MaxEntryDate
right join
    #general as c
    on
        (a.[Name] = c.[Name] or a.[Name] is null)
        and
        (
            (a.[Status] <> c.[Status] or (a.[Status] is null and c.[Status] is not null) or (a.[Status] is not null and c.[Status] is null))
            or (a.[lastLogon] <> c.[lastLogon] or (a.[lastLogon] is null and c.[lastLogon] is not null) or (a.[lastLogon] is not null and c.[lastLogon] is null))
            or (a.[LastLogonDate] <> c.[LastLogonDate] or (a.[LastLogonDate] is null and c.[LastLogonDate] is not null) or (a.[LastLogonDate] is not null and c.[LastLogonDate] is null))
            or (a.[lastLogonTimestamp] <> c.[lastLogonTimestamp] or (a.[lastLogonTimestamp] is null and c.[lastLogonTimestamp] is not null) or (a.[lastLogonTimestamp] is not null and c.[lastLogonTimestamp] is null))
            or (a.[ResolvedIP] <> c.[ResolvedIP] or (a.[ResolvedIP] is null and c.[ResolvedIP] is not null) or (a.[ResolvedIP] is not null and c.[ResolvedIP] is null))
            or (a.[Manufacturer] <> c.[Manufacturer] or (a.[Manufacturer] is null and c.[Manufacturer] is not null) or (a.[Manufacturer] is not null and c.[Manufacturer] is null))
            or (a.[Model] <> c.[Model] or (a.[Model] is null and c.[Model] is not null) or (a.[Model] is not null and c.[Model] is null))
            or (a.[Architecture] <> c.[Architecture] or (a.[Architecture] is null and c.[Architecture] is not null) or (a.[Architecture] is not null and c.[Architecture] is null))
            (a.[TotalPhysicalMemory] <> c.[TotalPhysicalMemory] or (a.[TotalPhysicalMemory] is null and c.[TotalPhysicalMemory] is not null) or (a.[TotalPhysicalMemory] is not null and c.[TotalPhysicalMemory] is null))
            or (a.[LastLoggedOnUser] <> c.[LastLoggedOnUser] or (a.[LastLoggedOnUser] is null and c.[LastLoggedOnUser] is not null) or (a.[LastLoggedOnUser] is not null and c.[LastLoggedOnUser] is null))
            or (a.[WakeUpType] <> c.[WakeUpType] or (a.[WakeUpType] is null and c.[WakeUpType] is not null) or (a.[WakeUpType] is not null and c.[WakeUpType] is null))
            or (a.[OperatingSystem] <> c.[OperatingSystem] or (a.[OperatingSystem] is null and c.[OperatingSystem] is not null) or (a.[OperatingSystem] is not null and c.[OperatingSystem] is null))
            or (a.[OperatingSystemVersion] <> c.[OperatingSystemVersion] or (a.[OperatingSystemVersion] is null and c.[OperatingSystemVersion] is not null) or (a.[OperatingSystemVersion] is not null and c.[OperatingSystemVersion] is null))
            or (a.[OperatingSystemArchitecture] <> c.[OperatingSystemArchitecture] or (a.[OperatingSystemArchitecture] is null and c.[OperatingSystemArchitecture] is not null) or (a.[OperatingSystemArchitecture] is not null and c.[OperatingSystemArchitecture] is null))
            or (a.[SystemDrive] <> c.[SystemDrive] or (a.[SystemDrive] is null and c.[SystemDrive] is not null) or (a.[SystemDrive] is not null and c.[SystemDrive] is null))
            or (a.[SerialNumber] <> c.[SerialNumber] or (a.[SerialNumber] is null and c.[SerialNumber] is not null) or (a.[SerialNumber] is not null and c.[SerialNumber] is null))
            or (a.[SMBIOSBIOSVersion] <> c.[SMBIOSBIOSVersion] or (a.[SMBIOSBIOSVersion] is null and c.[SMBIOSBIOSVersion] is not null) or (a.[SMBIOSBIOSVersion] is not null and c.[SMBIOSBIOSVersion] is null))
            or (a.[BIOSVersion] <> c.[BIOSVersion] or (a.[BIOSVersion] is null and c.[BIOSVersion] is not null) or (a.[BIOSVersion] is not null and c.[BIOSVersion] is null))
            or (a.[CPUName] <> c.[CPUName] or (a.[CPUName] is null and c.[CPUName] is not null) or (a.[CPUName] is not null and c.[CPUName] is null))
            or (a.[CPUCaption] <> c.[CPUCaption] or (a.[CPUCaption] is null and c.[CPUCaption] is not null) or (a.[CPUCaption] is not null and c.[CPUCaption] is null))
            or (a.[MaxClockSpeed] <> c.[MaxClockSpeed] or (a.[MaxClockSpeed] is null and c.[MaxClockSpeed] is not null) or (a.[MaxClockSpeed] is not null and c.[MaxClockSpeed] is null))
            or (a.[LastClockSpeed] <> c.[LastClockSpeed] or (a.[LastClockSpeed] is null and c.[LastClockSpeed] is not null) or (a.[LastClockSpeed] is not null and c.[LastClockSpeed] is null))
            or (a.[NumberOfProcessors] <> c.[NumberOfProcessors] or (a.[NumberOfProcessors] is null and c.[NumberOfProcessors] is not null) or (a.[NumberOfProcessors] is not null and c.[NumberOfProcessors] is null))
            or (a.[NumberOfCores] <> c.[NumberOfCores] or (a.[NumberOfCores] is null and c.[NumberOfCores] is not null) or (a.[NumberOfCores] is not null and c.[NumberOfCores] is null))
            or (a.[NumberOfThreads] <> c.[NumberOfThreads] or (a.[NumberOfThreads] is null and c.[NumberOfThreads] is not null) or (a.[NumberOfThreads] is not null and c.[NumberOfThreads] is null))
        )



-- udate the records in ADScanGeneral for any names that were not inserted
-- during the previous step
update a
set
    a.EntryDate = getdate()
from
    ADScanGeneral as a
inner join
    (
        select
            a.[Name], max(a.EntryDate) as MaxEntryDate
        from
            ADScanGeneral as a
        group by
            a.[Name]
    ) as b
    on
        a.[Name] = b.[Name]
        and
        a.EntryDate = b.MaxEntryDate
inner join
    #general as c
    on
        a.[Name] = c.[Name]
left join
    @inserted_names as d
    on
        a.[Name] = d.[Name]
where
    d.[Name] is null

这听起来是一个使用Merge命令的好地方。@JoeC-Huh,我还没听说过。我会查的,谢谢@所以我已经阅读了Merge命令,并在意识到它可能不起作用之前尝试实现它。不过我可能想的不对。当在target.Name=source.Name上使用source合并目标时,它检查的是名称列是否匹配,而不是整行,对吗?我需要它来检查整行是否匹配。有没有一种方法可以用Merge命令实现这一点?我已经在问题描述中添加了我尝试过的合并命令。您可以在添加时使用第一个表上的tragers,并检查添加的行(如果它已经存在于第二个表中)。您可以像在联接中一样使用多个字段。只需使用Target.Name=Source.Name和Target.Field2=Source.Field2。我不知道还有比列出所有列更简单的方法。这非常有用!非常感谢。我没有太多在多种条件下加入的经验,所以我认为这个查询实际上也帮助我学到了很多东西。我很感谢你为这个问题所做的工作。这正是我需要的。非常感谢!我似乎无法获取declare@inserted\u names[Name]varchar255;工作。我也不能在网上找到任何这种格式的文档。我应该如何在一个变量中存储整个列?编辑以显示正确的语法,这是一个快速响应!当我弄明白语法应该是什么时,我实际上是回来编辑我的评论的。谢谢你!