我正试图在我的SSIS进度日志中删除一些虚假警告。我在使用原始SQL来完成工作的任务中收到一堆关于未使用列的警告。我有一个数据流负责在加载新数据之前将数据存档到临时表中。数据流如下所示:
+--------------------+
| OLEDB Source task: |
| read staging table |
+--------------------+
|
|
+---------------------------+
| OLEDB Command task: |
| upsert into history table |
+---------------------------+
|
|
+---------------------------+
| OLEDB Command task: |
| delete from staging table |
+---------------------------+
我的'upsert'任务类似于:
--------------------------------------
-- update existing rows first...
update history
set field1 = s.field1
...
from history h
inner join staging s
on h.id = s.id
where h.last_edit_date <> s.last_edit_date -- only update changed records
-- ... then insert new rows
insert into history
select s.*
from staging s
join history h
on h.id = s.id
where h.id is null
--------------------------------------
清理任务也是一个SQL命令:
--------------------------------------
delete from staging
--------------------------------------
由于upsert任务没有任何输出列定义,我在日志中收到一堆警告:
[DTS.Pipeline] Warning: The output column "product_id" (693) on output
"OLE DB Source Output" (692) and component "read Piv_product staging table" (681)
is not subsequently used in the Data Flow task. Removing this unused output column
can increase Data Flow task performance.
如何消除对这些列的引用?我尝试过几个不同的任务,但似乎没有一个让我“吞下”输入列并将它们从任务的输出中抑制掉。我想保持我的日志清洁,所以我只看到真正的问题。有什么想法吗?
谢谢!
答案 0 :(得分:5)
全部联盟 - 仅选择您要传递的列 - 删除任何其他列。
我认为他们将在2008版本中解决此问题,以允许从管道中修剪/抑制列。
答案 1 :(得分:2)
好的,我在MSDN forums上找到了解决方法:
在任务1和2之间使用脚本组件转换;选择所有输入列;将脚本体留空。
消耗列,正确处理作业并且不记录任何警告。
仍然不清楚为什么我需要OLEDB源,因为任务2中的SQL连接到源表并完成所有工作,但是当我删除OLEDB源时数据流运行但不处理任何行,因此,临时表永远不会被清空,然后由于PK违规而导致在staging表中放置已更改行的下游进程失败。但那是另一天的问题。这有点笨重,但我的日志很干净。
答案 2 :(得分:1)
管道中的警告是由数据源中选择的列未在任何后续任务中使用而引起的。
轻松解决此问题的方法是双击数据源。在你的情况下(OLEDB源任务:| | read staging table)然后单击列并取消选择任何未来任务项中不需要的列。
这将从进度日志中删除这些警告。
然而,阅读上面的项目并按照其他答案的说明,您没有使用后续项目中的“来源任务”中的列,因此可以将其删除。
答案 3 :(得分:1)
我有同样的问题。我收到了一个很好的答案。你可以找到它here。
正如“Mark Wojciechowicz”所说:
以下是一些降低复杂性的建议,这反过来会提高性能:
答案 4 :(得分:0)
再次看你的问题,我认为你正在使用SSIS“反对谷物”。我并没有真正关注你从staging表中读取的内容,因为你的upsert似乎并不依赖于特定行中的任何内容,也不是清理。
在我看来,每行清理一次,但这没有用。
DataFlows通常不用于为管道中的每一行执行批量操作。如果您正在使用管道,则使用Lookup(或第三方TableDifference)组件处理UPSERT,然后将管道中的spli处理为OLEDB目标(BULK INSERT)和OLEDB命令(每个UPDATE一次)或另一个OLDEB目标。 “UPDATE临时表”。
通常,我会使用DataFlow来加载登台表而不进行任何拆分,然后在控制流中执行单个执行SQL任务,通过调用SP来执行直接SQL UPSERT中的所有其他操作(就像您一样)。 / p>
如果你不想拥有一个临时表,而不想读取一个平面文件并希望使用查找组件或其他东西执行UPDATE或INSERT,那么OLEDBCommand非常有用。但是它将在管道中的每一行被调用。
答案 5 :(得分:0)
你的DataFlow Task
应该以“upsert”结束。然后返回控制流,创建一个Execute SQL Task
,用于从暂存中删除。将您的DataFlow Task
链接到您的exec sql。
我没有为我的upsert使用第三方工具,但是就像Cade所建议的那样,即将您的数据流拆分为新的记录,只需转到OLE DB Destination
(或类似),并更新记录可以转到oledb命令进行更新。您可以使用合并连接或查找来拆分流。