首页 文章

使用带有临时表的存储过程生成带有BIML的SSIS包

提问于
浏览
4

正如大多数人所知,只要带有临时表的存储过程用作OleDbSource,SSIS就很难读取元数据 . 以前,通过添加SET FMTONLY OFF可以很容易地防止这种情况;在EXEC声明之前 . 这样做的缺点是存储过程在验证期间执行,这可能需要一段时间 . 从SQL 2012开始,我们可以使用WITH RESULT SETS来指定列及其数据类型 . SSIS会选择这一点,并且SQL语言都很好 .

但是,我想生成一个包含BIML的包,它使用这样的存储过程作为源,我无法让它工作 . 假设我有一个名为'dbo.csp_MyCsp'的存储过程,该过程使用名为'#MyTempTable'的临时表和1列'ColA int' . 我正在尝试使用以下(类似)Biml代码生成OleDbSource:

<OleDbSource ConnectionName="MyConnection" Name="OLE_SRC Test">
    <DirectInput>
        EXEC dbo.csp_MyCsp
        WITH RESULT SETS 
        (
            ([Col1] int)
        )
    </DirectInput>
</OleDbSource>

我收到一条错误,上面写着“无效对象#MyTempTable” . 奇怪的是,如果我打开一个包并在我的OleDbSource中粘贴该代码,它的工作没有任何错误 . 我有一种直觉,认为SSIS和BIML的验证步骤是不同的 .

你们有没有人有合适的解决方案?我不能使用FMTONLY OFF,因为存储过程需要一些时间来加载,这会导致生成超时 . 我正在使用SQL Server / SSIS 2014 .

提前致谢!

马文

2 回答

  • 1

    我以前自己遇到过这些问题 . 我使用了here描述的解决方案 . 最初的答案不是关于使用BIML生成,而是我在Visual Studio 2015中成功地将此解决方案与BIML Express一起使用 .

    我使用这个存储过程作为示例:

    CREATE PROCEDURE csp_MyCsp
    AS
    BEGIN
    
        SET NOCOUNT ON;
    
        IF 1 = 0
        BEGIN
            SELECT  CONVERT(INT, NULL) AS [database_id] 
            ,       CONVERT(SYSNAME, NULL) AS [name] 
        END;
    
        CREATE TABLE #mydatabases (
            [database_id] INT,
            [name] SYSNAME
        );
    
        INSERT INTO #mydatabases
        SELECT [database_id], [name]
        FROM sys.databases
    
        SELECT [database_id], [name]
        FROM #mydatabases
    
    END;
    

    这包含在我的BIML中:

    EXEC dbo.csp_MyCsp WITH RESULT SETS (
        (
            [database_id] INT,
            [database_name] SYSNAME
        )
    )
    
  • 0

    我在当前的Biml项目中遇到了类似的类似问题 . 像你提到的那样,问题似乎是Biml没有考虑存储过程中的临时表生成 .

    我的解决方案(解决方法?)是首先使它们成为全局临时表,而不仅仅是临时表 . 然后,我创建了一个新的存储过程,它运行与我的主存储过程相同的代码来处理临时表的创建 . 在Biml中运行'Generate Packages'之前,我在SSMS中打开一个新的查询窗口,运行该存储过程并保持该窗口打开(只要会话或此案例查询窗口打开,全局临时表就会持续) .

    这有点痛苦,但与此同时,它将我的存储过程的执行时间从35分钟缩短到5分钟,我只需要在“生成包”步骤中担心这一点,所以我会说是值得的 .

相关问题