Sql server 如何仅在任何列与另一个表中的匹配行不同时插入行
本质上,我是在收集我们网络上的计算机列表。我想比较我的临时表general中的信息,以便在我的AdscangGeneral表中找到一个特定的计算机名XXXX-XXXX-XXXXX。基本上,我想将general的计算机条目的列与ADScanGeneral中的最新条目进行比较,如果它们在任何地方不同,则将该行作为新条目一般输入ADScanGeneral。否则,如果它们相同,则只需更新该计算机的ADScanGeneral.EntryDate列 我的问题是,如果不进行长时间的循环,我想不出一种方法来比较单个条目的列general和AdscangGeneral。这在SQL语句中可能吗 我的下表示例: 一般的Sql server 如何仅在任何列与另一个表中的匹配行不同时插入行,sql-server,tsql,insert,compare,Sql Server,Tsql,Insert,Compare,本质上,我是在收集我们网络上的计算机列表。我想比较我的临时表general中的信息,以便在我的AdscangGeneral表中找到一个特定的计算机名XXXX-XXXX-XXXXX。基本上,我想将general的计算机条目的列与ADScanGeneral中的最新条目进行比较,如果它们在任何地方不同,则将该行作为新条目一般输入ADScanGeneral。否则,如果它们相同,则只需更新该计算机的ADScanGeneral.EntryDate列 我的问题是,如果不进行长时间的循环,我想不出一种方法来比较
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;工作。我也不能在网上找到任何这种格式的文档。我应该如何在一个变量中存储整个列?编辑以显示正确的语法,这是一个快速响应!当我弄明白语法应该是什么时,我实际上是回来编辑我的评论的。谢谢你!