如果任何列与另一个表中的匹配行不同,如何插入行

问题描述 投票:1回答:1

基本上我在我们的网络上提取计算机列表。我想在我的临时表#general中比较我的ADScanGeneral表中特定计算机名称XXXX-XXXX-XXXXX的信息。基本上我想将#general的计算机条目列与ADScanGeneral中的最新条目进行比较,如果它们在任何地方不同,则将#general中的行输入ADScanGeneral作为新条目。否则,如果它们相同,则只需更新该计算机的ADScanGeneral.EntryDate列。

我的问题是我想不出一种方法来比较#general和ADScanGeneral中单个条目的列,而不需要做很长的循环。这在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,因此我希望将整个条目作为新条目插入到ADScanGeneral中。第二个条目,没有任何改变,所以我想更新ADScanGeneral中的输入日期。第三个条目有一个更新的lastLogon,所以我想将它作为一个新的条目添加到ADScanGeneral中。

那有意义吗?如果您需要澄清,请询问,我会尽力帮助您。谢谢大家的帮助!

JoeC建议检查合并命令,但它似乎只匹配您在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
                );
sql-server tsql insert compare
1个回答
1
投票

实现此目的的一种方法是使用output clause跟踪已插入的名称,并在筛选后在第二个查询中执行更新以删除插入的名称。

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

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
© www.soinside.com 2019 - 2024. All rights reserved.