-1

我使用这个脚本创建了一个表。

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 命令来更新表中的数据。

4

1 回答 1

3

您的 OLE DB Source 命令应该是一个标识候选记录池的查询。如果您因为知道某个范围无效而可以消除该范围,请在此处应用过滤器。例如,您只加载当前年份的数据,然后您将应用过滤器,SELECT T.* FROM Country.dbo.Table AS T WHERE T.year = 2013或者您正在加载最近 30 天或您的源范围可能是什么。

这将允许行流入您的数据流。从那里,您希望对参考/目标集的可用行执行更改检测。由于您需要考虑更改行,因此您可能需要一些标准来确定已更改的内容与用于匹配条件的内容。在我们的数据仓库中,我们有两个哈希键:history 和 change。历史是通过 HASHBYTES 函数散列在一起的业务键,而更改键是散列在一起的非业务键。在我们的第一次查找中,我们测试当前行的历史哈希值和参考集的更改键是否存在。如果两者都匹配,那么我知道当前行存在于我的数据集中并且值相同,因此被路由到行数,然后被路由到位桶。

在第一次查找的不匹配输出中,我知道这是一个全新的行,或者是对现有行的更改。我需要执行第二次查找以确定哪个是真的,所以添加另一个查找组件,这次只匹配历史哈希键。如果我找到匹配项,那么我需要执行更新。否则,我有一个新行。

除非您的数据集很小,而不是使用 OLE DB 命令来执行更新,否则通过将更新暂存到表并在数据流完成后执行执行 SQL 任务以实际执行更新,您可能会获得更好的性能。原因是 OLE DB 命令(不要与 OLE DB 目标混淆)执行单例数据库操作,这与正确 ETL 的基于集合的性质相反。

Andy Leonard 有一个很棒的系列,集成服务的阶梯,他在其中详细介绍了增量负载模式。

于 2013-10-29T03:53:06.960 回答