我是SSIS的新手,需要这方面的帮助。我找到了article,它描述了如何检测存在的行和已更改的行。我缺少的部分是如何更新已更改的行。我发现一些文章说它也是删除已更改的记录并插入新记录集的好方法。问题是我不知道该如何删除(红色框)。
有什么建议吗?
答案 0 :(得分:20)
如果必须删除数据流任务中的行,则需要使用OLE DB Command
转换并编写类似DELETE FROM dbo.Table WHERE ColumnName = ?
的DELETE语句。然后,在OLE DB命令转换的列映射中,您将使用来自上一个转换的数据映射问号所表示的参数。在您的情况下,来自Union All 2的数据。
但是,我不建议使用该选项,因为 OLE DB Command 会对每一行执行,如果行数过多,可能会降低包的速度。
我会推荐这样的东西:
使用 OLE DB目标将Union All 2
的输出重定向到临时临时表(例如 dbo.Staging )。
让我们假设您的最终目的地表是 dbo.Destination 。现在,您的Staging表包含应从表Destination中删除的所有记录。
在控制流标签上,在Execute SQL Task
后面放置Data Flow Task
。在执行SQL任务中,编写SQL语句或使用将调用SQL语句的存储过程来连接Staging和Destination之间的记录,以从Destination表中删除所有匹配的行。
此外,在数据流任务之前放置另一个执行SQL任务。在此“执行SQL任务”中,从“临时表”中删除/截断行。
这样的东西可能会删除行:。
DELETE D
FROM dbo.Destination D
INNER JOIN dbo.Staging S
ON D.DestinationId = S.StagingId
希望有所帮助。
答案 1 :(得分:1)
除user756519 answer之外。如果您有数百万条记录要删除ExecuteSQL的最后一步(4),则可以使用以下内容批量完成删除语句:
WHILE (1=1)
BEGIN
DELETE D
from dbo.Destination D
inner join
(
-- select ids that should be removed from table
SELECT TOP(10000) DestinationId
FROM
(
SELECT
D1.DestinationId,
S.StagingId
from
dbo.Destination as D1
LEFT JOIN
dbo.Staging as S
ON
D1.DestinationId = S.StagingId
) AS G
WHERE
StagingId IS NULL
) as R
on D.DestinationId = R.DestinationId;
IF @@ROWCOUNT < 1 BREAK
-- info message
DECLARE @timestamp VARCHAR(50)
SELECT @timestamp = CAST(getdate() AS VARCHAR)
RAISERROR ('Chunk deleted %s', 10, 1,@timestamp) WITH NOWAIT
END
答案 2 :(得分:-4)
我建议您使用Spoon(Kettle)它更灵活,它有一个名为“维度查找/更新”的设计工具,可以帮助您维护维度表,您可以指定您想要的操作取决于列的更改(更新记录,插入新记录)所有这些都基于记录的时间版本控制。