SSIS包不想获取临时表的元数据

时间:2013-08-20 23:21:04

标签: sql sql-server ssis ssis-2012

我有一个SSIS包,其中包含多个流程。

每个流程都负责创建一个“临时”表,该表在创建后填满。 这些表是全局临时表。

我为另一张表添加了一个额外的流程(我没有制作包装),其完全如上所述。但是,出于某种原因,程序包在此流程中间歇性地失败,而除了一些表名之外,它与其他程序完全相同。

不断弹出的错误:

  

更新 - 插入数据流:错误:SSIS错误代码DTS_E_OLEDBERROR。一个   发生OLE DB错误。错误代码:0x80004005。 OLE DB记录是   可用。来源:“Microsoft SQL Server Native Client 11.0”   Hresult:0x80004005描述:“未指定的错误”。 OLE DB   记录可用。来源:“Microsoft SQL Server Native Client   11.0“Hresult:0x80004005说明:”无法确定元数据,因为语句'select * from   '## TmpMcsConfigurationDeviceHistory86B34BFD041A430E84CCACE78DA336A1''使用临时表。“。

创作表达:

"CREATE TABLE " + @[User::TmpMcsConfigurationDeviceHistory]  + " ([RecId] [bigint] NULL,[DataAreaID] [nvarchar](4) COLLATE database_default NULL,[Asset] [bigint] NULL,[Code] [nvarchar](255) COLLATE database_default NULL,[Configuration] [bigint],[StartdateTime] [datetime] NULL,[EndDateTime] [datetime] NULL)

解析表达式(=已评估):

CREATE TABLE ##TmpMcsConfigurationDeviceHistory764E56F088DC475C9CC747CC82B9E388 ([RecId] [bigint] NULL,[DataAreaID] [nvarchar](4) COLLATE database_default NULL,[Asset] [bigint] NULL,[Code] [nvarchar](255) COLLATE database_default NULL,[Configuration] [bigint],[StartdateTime] [datetime] NULL,[EndDateTime] [datetime] NULL)

6 个答案:

答案 0 :(得分:34)

Using WITH RESULT SETS to explicitly define the metadata将允许SSIS跳过sp_describe_first_result_set步骤并使用您定义的元数据。好处是你可以使用它来让SSIS执行包含临时表的SQL(对我来说,这个性能有很大帮助);缺点是,如果有任何变化,你必须手动维护和更新它。

查询示例(存储过程:)

    EXEC ('dbo.MyStoredProcedure')
    WITH RESULT SETS
      (
        (
            MyIntegerColumn INT NOT NULL,
            MyTextColumn VARCHAR(50) NULL,
            MyOtherColumn BIT NULL
        )
      )

查询示例(简单SQL:)

EXEC ('
    CREATE TABLE #a 
      (
        Col INT
      ) 
    INSERT INTO #a 
      (
        COL
      )
    SELECT 1 AS Col

    SELECT Col 
    FROM #a')
WITH RESULT SETS ( (Col INT NOT NULL))
  )

答案 1 :(得分:15)

另一种选择(一种黑客,但它的工作原理并且不需要你改变对全局临时表的使用)是在实际查询前使用SET FMTONLY ON命令发送假的“第一个结果”使用正确的列结构设置“到SSIS”。所以你可以做类似

的事情
SET FMTONLY ON
select 0 as a, 1 as b, 'test' as C, GETDATE() as D
SET FMTONLY OFF

select a, b, c, d from ##TempTable

当SSIS运行sp_describe_first_result_set时,它将返回FMTONLY命令的元数据和列名,并且不会抱怨无法确定临时表的元数据,因为它甚至都不会尝试。

答案 2 :(得分:9)

如果您正在使用SSIS 2012,那么它使用系统存储过程 sp_describe_first_result_set 来获取表的元数据,并且它不支持临时表。但你可以选择其他选项,如表变量和CTE,它们可以正常工作。 https://connect.microsoft.com/SQLServer/feedback/details/629077/denali-engine-metadata-discovery-shuns-temp-tables

答案 3 :(得分:0)

我发现问题出现在GUID重复的问题中,我复制了元素(比如创建临时表的那个),并且在复制时它们都收到了相同的guid。我使用了一个工具来重置我的包中的所有这些guid,这解决了我的问题。

谢谢!

答案 4 :(得分:0)

与我们使用临时表进行暂存相同的问题。花了一些时间后,找到了解决方法。

在OLE DB / ADO目标数据流任务中,您可以在其中指定登台表的名称。

将AccessMode属性更改为SQL命令而不是OpenRowSet,并将SQL Command属性指定为"从#temp"中选择*。

华友世纪,它按预期工作。

此处捕获的是当您指定除SQL命令之外的访问模式时,SSIS期望它是一个表/视图,并且它将SSIS更改为调用sp_describe_first_result_set以获取元数据。但是当你指定SQL命令时,它会期待一个查询或SP命令等。幸运的是,它仍然使用旧的获取元数据的方式。

http://social.msdn.microsoft.com/Forums/sqlserver/en-US/cfe1c7c1-910a-4f52-9718-c3406263b177/usage-of-temp-tables-in-ssis-2012?forum=sqlintegrationservices#cfe1c7c1-910a-4f52-9718-c3406263b177

答案 5 :(得分:0)

当SSSI软件包从2008年迁移到2016年时,我遇到了类似的问题。最新版本使用sp_describe_first_result_set来获取元数据,并且不适用于临时表。作为解决方法,我在OLEDB源代码编辑器中使用了以下查询。我没有更改SQL存储过程,它仍然使用一个临时表。请确保使用解析查询和预览选项以确保其正常工作。请参见下图。

查询:

EXEC [dbo].[spGetNames]
WITH RESULT SETS((
        FirstName varchar(50), 
        LastName varchar(50)
));

See Image