在SSIS中使用临时表

时间:2009-10-16 17:54:47

标签: visual-studio-2008 sql-server-2008 ssis

我在SQL Server中使用存储过程中的临时表。 我试图在OLE DB源代码编辑器中使用该SP。

我可以看到在Build Query按钮附带的Query Builder中返回的数据输出。 但是,当我单击列选项卡时,我收到以下错误。

  

- TITLE:Microsoft Visual Studio

     

数据流任务错误[OLE DB源[1]]:SSIS错误代码   DTS_E_OLEDBERROR。发生OLE DB错误。错误代码:   0x80004005的。 OLE DB记录可用。资料来源:“Microsoft SQL   Server Native Client 10.0“Hresult:0x80004005说明:”无效   对象名称'## Payment'。“。

     

数据流任务错误[OLE DB源[1]]:无法检索列   来自数据源的信息。确保您的目标表在   数据库可用。

这是否意味着我无法在SP中使用临时表,如果我希望它被SS​​IS使用

7 个答案:

答案 0 :(得分:15)

http://sqlserverpedia.com/blog/sql-server-bloggers/ssis-stored-procedure-metadata/提到了另一种解决方案。看看选项3。

引用: 添加一些元数据和"设置nocount on"使用"短路if条款"到存储过程(如果1 = 0),并在顶部有一个虚假的select语句。我试图离开"设置nocount"出来,它没有用。

CREATE PROCEDURE [dbo] . [GenMetadata] AS 
SET NOCOUNT ON 
IF 1 = 0 
    BEGIN
         -- Publish metadata 
        SELECT   CAST (NULL AS INT ) AS id , 
                CAST (NULL AS NCHAR ( 10 )) AS [Name] , 
                CAST (NULL AS NCHAR ( 10 )) AS SirName 
    END 

 -- Do real work starting here 
CREATE TABLE #test 
    ( 
      [id] [int] NULL, 
      [Name] [nchar] ( 10 ) NULL, 
      [SirName] [nchar] ( 10 ) NULL 
    ) 

答案 1 :(得分:8)

我用过

设置FMTONLY OFF 在过程开始时,它将告诉不要将行处理到客户端 当它没有被执行时 因为在解析SP时没有临时表,因此在解析时没有可用的列。

它让我终于工作了:)

答案 2 :(得分:5)

如果在BIDS中出现错误,则ajdams解决方案将无法正常工作,因为它仅适用于从SQL Server代理运行包时引发的错误。

主要问题是SSIS正在努力解决元数据。从它的立场来看,##表不存在,因为它不能在预执行阶段返回对象的元数据。所以你必须找到一种方法来满足表已经存在的要求。有几个解决方案:

  1. 不要使用临时表。而是创建一个工作数据库并将所有对象放入其中。显然,如果您尝试在服务器上获取数据而不是像生产服务器这样的dbo,这可能不会起作用,因此您不能依赖此解决方案。

  2. 使用CTE而不是临时表。如果源服务器是2005/2008,则此方法有效。如果源服务器是2000,这将无济于事。

  3. 在单独的Execute SQL命令中创建##表。将连接的RetainSameConnection属性设置为True。将DelayValidation设置为true以表示数据流。设置数据流时,通过临时将SELECT TOP 0字段= CAST(NULL AS INT)添加到存储过程的顶部来伪造它,该存储过程具有与最终输出相同的元数据。在运行程序包之前,请记住从存储过程中删除它。这也是在数据流之间共享临时表数据的便捷技巧。如果您希望包的其余部分使用单独的连接以便它们可以并行运行,那么您必须创建一个额外的非共享连接。这避免了问题,因为在数据流任务运行时临时表已经存在。

  4. 选项3实现了您的目标,但它很复杂,并且您必须将create ##命令分隔到另一个存储过程调用中。如果您能够在源服务器上创建存储过程,那么您可能还可以创建其他对象(如登台表),这通常是更好的解决方案。它还可以兼顾可能的TempDB争用问题,这也是一个理想的好处。

    祝您好运,如果您需要有关如何实施第3步的进一步指导,请告诉我。

答案 3 :(得分:2)

不,这是一个权限问题。这应该可以帮到你:

http://support.microsoft.com/kb/933835

答案 4 :(得分:1)

对于所有涉及的麻烦,我认为这可能是不值得的。在db中创建一个真实的表,并在加载之前/之后截断它。如果它是一个数据仓库,那么如果你有一两个额外的表,那就不重要了。这为您提供了设计时SSIS工具,这意味着您不必担心临时表的内部。

如果要将事物分开,则只需在单独的模式中创建SSIS临时表。您可以使用权限使此schmema对所有其他用户不可见。

CREATE SCHEMA [ssis_temp]

CREATE TABLE [ssis_temp].[tempTableName]

答案 5 :(得分:1)

这些步骤对我有所帮助:

  1. 将最终结果集写入表格。
  2. 将该表作为CREATE编写到新的新查询编辑器窗口中。
  3. 删除除定义列的打开和关闭括号以外的所有内容。
  4. 将其包裹在另一对括号中。
  5. 重新调用您的SP

    exec p_MySPWithTempTables?,?

  6. exec p_MySPWithTempTables ?, ? with result sets
    (
        (
            ColumnA int,
            ColumnB varchar(10),
            ColumnC datetime
        )
    )
    

答案 6 :(得分:0)

您可以使用表变量而不是临时表。它会起作用