33

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

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

我为另一个表添加了 1 个额外的流(我没有制作包),它完全按照上面的说明进行。但是,由于某种原因,包在此流程中间歇性地失败,而除了一些表名之外,它与其他包完全相同。

不断弹出的错误:

更新 - 插入数据流:错误: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)
4

6 回答 6

52

使用WITH RESULT SETS显式定义元数据将允许 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 
      (
        MyIntegerColumn INT NOT NULL,
        MyTextColumn VARCHAR(50) NULL,
        MyOtherColumn BIT NULL
      ) 
    INSERT INTO #a 
      (
        MyIntegerColumn,
        MyTextColumn,
        MyOtherColumn
      )
    SELECT 
        1 AS MyIntegerColumn,
        ''x'' AS MyTextColumn,
        0 AS MyOtherColumn

    SELECT MyIntegerColumn, MyTextColumn, MyOtherColumn
    FROM #a')

WITH RESULT SETS
    (
        (
            MyIntegerColumn INT NOT NULL
           ,MyTextColumn VARCHAR(50) NULL
           ,MyOtherColumn BIT NULL
        )
    )
于 2015-02-04T18:29:56.803 回答
16

另一种选择(一种 hack,但它有效,并且不需要您更改对全局临时表的使用)是在实际查询前使用 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 命令的元数据和列名,并且不会抱怨无法确定临时表的元数据,因为它甚至不会尝试。

于 2013-08-21T14:31:33.843 回答
9

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

于 2013-08-20T23:39:53.597 回答
2

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

询问:

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

看图片

于 2020-06-22T15:59:21.417 回答
1

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

在 OLE DB/ADO Destination of Data flow 任务中指定临时表的名称。

将 AccessMode 属性更改为 SQL 命令而不是 OpenRowSet,并将 SQL 命令属性指定为“select * from #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

于 2014-04-01T14:24:47.963 回答
0

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

谢谢!

于 2013-08-26T22:44:30.317 回答