Ssis SSI没有返回任何列

Ssis SSI没有返回任何列,ssis,Ssis,我正在实现一个SSIS包,目前正在尝试执行以下操作 截断目标表 通过执行存储过程获取数据并将其插入目标表。 我创建了一个执行SQL任务来处理步骤1,并使用oledb源和oledb目标创建了数据流来处理第二个点。到目前为止,它一直在成功地工作,但对于使用临时表的my存储过程来说,它不起作用 当我编辑oledb源代码并单击预览按钮时,我得到一个没有返回列的错误 我知道SSIS在执行依赖于临时表的存储过程时在生成列方面存在问题。我已经将存储的proc转换为使用临时表变量,现在在预览时它可以在SSIS中

我正在实现一个SSIS包,目前正在尝试执行以下操作

截断目标表 通过执行存储过程获取数据并将其插入目标表。 我创建了一个执行SQL任务来处理步骤1,并使用oledb源和oledb目标创建了数据流来处理第二个点。到目前为止,它一直在成功地工作,但对于使用临时表的my存储过程来说,它不起作用

当我编辑oledb源代码并单击预览按钮时,我得到一个没有返回列的错误

我知道SSIS在执行依赖于临时表的存储过程时在生成列方面存在问题。我已经将存储的proc转换为使用临时表变量,现在在预览时它可以在SSIS中返回列。唯一的缺点是存储过程的执行时间较长。它需要1小时15分钟,而使用临时表需要15分钟

我确实看到一个建议,在执行存储过程之前使用SET FMTONLY作为更改为临时表变量的替代解决方案,但这似乎不起作用,因为我遇到了语法或权限拒绝错误


谁能告诉我一个不影响性能的问题解决方案。

听起来您已经阅读了SSI中使用临时表的所有方法,包括IF 1=0。。。戏法如果你还没看过,用谷歌搜索一下

您说使用表变量会导致存储过程花费的时间是使用临时表的5倍左右。最有可能的原因是您正在为临时表编制索引,而不是为表变量编制索引。如果您不知道表变量可以被索引,那么它们可以。你可以试试

最后,您没有提到的一个解决方案是,您可以将临时表替换为实际表,当您使用完临时表后,该表会被截断。

简短评论:

使用结果集尝试EXEC,并为带有临时表的proc自己指定元数据;或者使用脚本组件作为源,自己指定输出列

长篇评论:

从技术上讲,在SSI中使用的驱动程序/数据库将决定使用临时表时的行为

在使用SSIS的管道组件时,元数据是一个重要因素。所谓元数据,我指的是管道组件使用的列的名称、它们的数据类型等。在设计数据流时,某人/某物应该向需要它的组件提供此元数据

在大多数情况下,SSI会自动检索元数据。未连接到外部数据源的组件(如条件拆分等)从所连接的其他组件获取元数据。对于连接到外部数据源(如Oledb源、Oledb目标、查找等)的管道组件,SSIS提供了一种无需人工参与即可获取此元数据的机制。此机制涉及驱动程序连接到数据库并检索输出的元数据。如果驱动程序/数据库能够返回元数据,则使用该元数据。如果驱动程序/数据库无法运行,则会出现所看到的错误。我其余的评论都是基于这样的假设,即您在提问时使用的是SQL Server数据库

在SSIS中使用SQL Server数据库时,通常使用Microsoft提供的本机客户端驱动程序。当试图获取元数据时,这些驱动程序试图在不实际执行SQL语句的情况下获取元数据。实际执行可能会产生副作用;而且,可能需要几秒钟/分钟/小时以上;而且,在软件包设计期间,您不希望出现副作用和长时间等待。因此,为了获得元数据,驱动程序依赖于sql命令中使用的实际对象的元数据。如果该命令使用物理表或视图,则SQL Server已经具有可用的元数据,并且可以将其提供给驱动程序。如果是临时表,SQL Server在能够创建临时表之前不会有元数据。如果使用FMT ONLY选项,您可以以这种方式使用它来创建临时表,但可以避免任何繁重的处理/副作用,从而能够检索元数据而不会受到惩罚。2012年之后,这些本机客户端驱动程序依赖于比2012年之前的驱动程序更新的功能来检索元数据。2012年及以后,驱动程序使用sp_descripe_first_result_set proc检索元数据。因此,能否获取元数据取决于sp_descripe_first_result_set proc的能力

因此,尽管SSI可以因为驱动程序/数据库而自动获取元数据,但在某些情况下,它不会因为驱动程序/数据库而再次自动获取元数据。在涉及第二个场景的情况下,其他一些流程(通常是人工)可以帮助驱动程序推断元数据或直接向组件提供元数据

为了帮助驱动程序,对于SQL Server 2012及其后版本,可以使用WITH RESULTSETS子句指定输出元数据。当存在此子句时,驱动程序将使用它,并且不会尝试从系统对象查询元数据;这样就避免了你可能会犯的错误。如果您使用的是SQL Server 2008附带的驱动程序,则只能使用FMT。此选项位于驱动程序/数据库级别

另一个选项是使用脚本组件作为源,并在输出列中指定列/元数据。在这种情况下,SSI不会尝试从数据源检索元数据,而是依赖于您在脚本组件的输出部分中提供的定义


如您所见,这两个选项都涉及到指定元数据的人工或其他进程,而不是SSI尝试以自动化方式检索元数据。如果使用SQL Server,我更喜欢第一个选项,如果使用MySql之类的数据库,我更喜欢第二个选项。

感谢您的输入,我尝试了1=0。它在内部告诉SSI调用SET FMTONLY ON,最终我得到了与上面提到的相同的错误。我尝试了临时变量,它似乎非常慢。我现在正在尝试物理表,并将很快更新您的物理表也需要很多时间。我创建了与临时表相同的索引。不确定为什么要使用实际表检查执行计划,并查看是否正在使用索引。还有,使用1=0技巧得到的确切错误是什么?嘿,Tab。问题已解决。我刚刚注意到其中一个表上缺少索引,现在执行速度很快。SP使用的是哪个版本的SQL server?