我根据某些条件从table A(Source)
查询了一些数据,并在插入Crm之前插入temp table(Destination)
。
如果Crm中已存在数据,我不想查询来自table A
和insert into temp table(I want this table to be empty)
的数据,除非该数据中有更新或创建了新数据。所以基本上我只想查询新数据,或者是否存在已经存在于Crm中的表A中的任何修改数据。目前我的数据流是这样的。
在source table A
我audit columns
:createdOn
和modifiedOn
。
我找到了一种方法。 SSIS DataFlow - copy only changed and new records但不清楚如何这样做。 实现这一目标的最佳和简单方法是什么。
答案 0 :(得分:1)
您发布的链接基本上是说要暂存所有内容并使用MERGE
更新您的表格(主要是UPDATE
/ INSERT
)。
通过从table A
部分选择,我能够真正想到让您的流程更快(在很大程度上)的唯一方法是将“上次更新”的时间戳添加到table A
并强制执行它总是最新的。
一种方法是使用触发器;请参阅here以获取示例。
然后,您可以根据该时间戳进行选择,或者保留每次运行SSIS包时使用的最后一个时间戳的记录,然后为其添加安全范围。
编辑:我刚看到您已经有modifiedOn
列,因此您可以按照上述说明使用该列。
示例:
有几种不同的方法可以做到:
<强> ONE 强>
在最终目的地表格中加入modifiedOn
列。
然后,您可以在SSIS字符串变量中为数据流源构建动态查询,例如:
"SELECT * FROM [table A] WHERE modifiedOn >= DATEADD(DAY, -1, '" + @[User::MaxModifiedOnDate] + "')"
@[User::MaxModifiedOnDate]
(字符串变量)将来自执行SQL任务,您可以在其中写入以下查询的结果:
SELECT FORMAT(CAST(MAX(modifiedOn) AS date), 'yyyy-MM-dd') MaxModifiedOnDate FROM DestinationTable
DATEADD
部分以及CAST
在一定程度上代表了您的安全边际。
<强> TWO 强>
如果这不是一个选项,您可以保留一个数据加载历史记录表,告诉您何时需要加载,例如:
CREATE TABLE DataLoadHistory
(
DataLoadID int PRIMARY KEY IDENTITY
, DataLoadStart datetime NOT NULL
, DataLoadEnd datetime
, Success bit NOT NULL
)
您将使用此开始每个数据加载(执行SQL任务):
CREATE PROCEDURE BeginDataLoad
@DataLoadID int OUTPUT
AS
INSERT INTO DataLoadHistory
(
DataLoadStart
, Success
)
VALUES
(
GETDATE()
, 0
)
SELECT @DataLoadID = SCOPE_IDENTITY()
您可以将返回的DataLoadID
存储在SSIS整数变量中,并在数据加载完成后使用它,如下所示:
CREATE PROCEDURE DataLoadComplete
@DataLoadID int
AS
UPDATE DataLoadHistory
SET
DataLoadEnd = GETDATE()
, Success = 1
WHERE DataLoadID = @DataLoadID
在为table A
构建查询时,您将以与以前相同的方式(使用动态生成的SQL查询)执行此操作,但MaxModifiedOnDate
将来自以下查询:
SELECT FORMAT(CAST(MAX(DataLoadStart) AS date), 'yyyy-MM-dd') MaxModifiedOnDate FROM DataLoadHistory WHERE Success = 1
所以是DataLoadHistory
表,而不是目的地表。
请注意,这会在第一次运行时失败,因为历史记录表上没有成功的条目,因此您需要插入虚拟记录,或者找到其他方法。
<强>三强>
我已经看到它在很多地方做了很多,比如你的数据负载每天都在运行,你只需要过去7天,或类似的东西,你肯定永远不会通过一些安全边际(因为正在监视进程的失败)。
这不是我的首选方案,但它很简单,如果您对该流程的监控程度有信心,则可以正常工作。