我有一个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)
答案 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命令等。幸运的是,它仍然使用旧的获取元数据的方式。
答案 5 :(得分:0)
当SSSI软件包从2008年迁移到2016年时,我遇到了类似的问题。最新版本使用sp_describe_first_result_set
来获取元数据,并且不适用于临时表。作为解决方法,我在OLEDB源代码编辑器中使用了以下查询。我没有更改SQL存储过程,它仍然使用一个临时表。请确保使用解析查询和预览选项以确保其正常工作。请参见下图。
查询:
EXEC [dbo].[spGetNames]
WITH RESULT SETS((
FirstName varchar(50),
LastName varchar(50)
));