我使用这个脚本创建了一个表。
use DWResourceTask
go
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[DimEntity]') AND type in (N'U'))
DROP TABLE [DimEntity]
Go
Create Table DimEntity
(EntityKey int NOT NULL identity PRIMARY KEY,
[EntCode] [nvarchar](8) NOT NULL,
[Name] [nvarchar](80) NOT NULL,
[CompanyRegistration] [nvarchar](80) NULL,
[Active] [int] NOT NULL,
[AccessLevel] [int] NOT NULL ,
[SiteURN] [nvarchar](128) NOT NULL,
[CompanyURN] [nvarchar](128) NOT NULL,
[SiteName] [nvarchar](30) NOT NULL,
[SiteDesc] [nvarchar](60) NULL,
[SiteURL] [nvarchar](512) NOT NULL)
我使用此
插入数据Select e.EntCode, e.Name, e.Active, e.AccessLevel, ss.SiteURN, ss.CompanyURN,
ss.SiteName, ss.SiteDesc, ss.SiteURL
from USA.dbo.SCSite ss, USA.dbo.SCLegalEnt e
where ss.localsiteflag = 1
and e.active = 1
UNION ALL
Select e.EntCode, e.Name, e.Active, e.AccessLevel, ss.SiteURN, ss.CompanyURN,
ss.SiteName, ss.SiteDesc, ss.SiteURL
from UK.dbo.SCSite ss, UK.dbo.SCLegalEnt e
where ss.localsiteflag = 1
and e.active = 1
我想要做的是我计划创建一个SSIS包,无论我执行多少次,它都只会插入新记录或/和更新现有记录。过程应该是可重复的。
我应该在OLE DB源的SQL命令中放入什么脚本来插入“仅”新记录或/和更新现有记录。
是某种更新命令吗?但是怎么样?我不瘦我需要truncate或delete命令来更新表中的数据。
答案 0 :(得分:3)
您的OLE DB Source命令应该是一个标识候选记录池的查询。如果您可以消除范围,因为您知道它无效,请在此处应用过滤器。例如,您只是加载当前年度数据,然后您应用了SELECT T.* FROM Country.dbo.Table AS T WHERE T.year = 2013
之类的过滤器,或者您最近30天或者您的源范围可能会加载。
这将允许行流入您的数据流。从那里,您需要对参考/目标集的可用行执行更改检测。由于您需要考虑更改行,因此您可能需要一些标准来确定更改内容与用于匹配条件的更改内容。在我们的数据仓库中,我们有两个哈希键:历史和更改。历史记录是通过HASHBYTES函数将业务键拼接在一起,而更改键是非业务键一起散列的。在我们的第一次查找中,我们测试当前行的历史哈希的存在以及引用集的更改密钥。如果两者都匹配,那么我知道我的数据集中存在当前行,并且值相同,因此路由到行计数然后关闭到位桶。
在第一次查找的无匹配输出中,我知道这是一个全新的行,或者它是对现有行的更改。我需要执行第二次查找以确定哪个是真的,因此添加另一个查找组件,这次只匹配历史哈希键。如果我找到匹配项,那么我需要执行更新。否则,我有一个新行。
除非您的数据集很小,而不是使用OLE DB命令来执行更新,否则在数据流完成以实际执行更新后,通过暂停对表的更新并执行执行SQL任务,可能会获得更好的性能。原因是OLE DB命令,不要与OLE DB Destination混淆,执行单独的数据库操作,这与正确的ETL的基于集合的性质相反。
Andy Leonard有一个很棒的系列,Stairway to Integration Services,详细介绍了增量加载模式。