2013-04-29 84 views
0

我正在使用SQL Server 2008 R2,并试图将存储过程的结果导入临时表中,以便稍后在调用存储过程中访问。我的TSQL如下:无法将存储过程的结果导入#TempTable工作

CREATE PROCEDURE sp_ToBeCalled AS 
(
    @SomeParam INT 
) 
BEGIN 
    SELECT * FROM tblSomeTable WHERE SomeField = @SomeParam 
END 


CREATE PROCEDURE sp_CallingProcedure AS 
(
    @SomeOtherParam INT 
) 
BEGIN 
    -- A 
    SELECT * INTO #MyTempTable FROM sp_ToBeCalled(@SomeOtherParam) 

    -- B 
    SELECT * FROM #MyTempTable FOR XML RAW 
END 

这一切编译罚款但是当我打电话sp_CallingProcedure声明 - B返回一个错误#MyTempTable。

我该如何做“A”,以便我可以从#MyTempTable表中访问其结果,而无需首先声明#MyTempTable的结构?

我正在寻找可以一般使用的解决方案。我有一些现有的存​​储过程,我需要从不同的调用者调用获取结果可查询的必要性。我无法更改现有的存储过程。

我不想使用

  1. OPENQUOERY() - 需要自定义链接服务器定义
  2. sp_ExecSql() - 意味着我必须建立动态SQL不给我SP编译时检查。
+0

你可能要考虑表值函数以及 – Sparky 2013-04-29 22:29:16

+0

你可以使用OPENROWSET来代替OPENQUERY以避免链接服务器定义。我试图让MS实现一个EXECUTE INTO,但他们关闭,因为不会修复。 https://connect.microsoft.com/SQLServer/feedback/details/675710/execute-into-to-capture-execute-results-in-a-new-table – GilM 2013-04-29 22:37:46

回答

1

您正在尝试使用类似于表格函数的过程。

使用try

INSERT INTO #MyTempTable (column1, column2...) 
exec sp_ToBeCalled(@SomeOtherParam) 
+1

OP不想定义temp的结构表填充之前。 – GilM 2013-04-29 22:45:46

+0

那么请忽略列表? – 2013-04-30 01:24:34

+0

@Gilm:“TheEdge”希望能够提出一个解决方案,他不必更改存储过程,也不使用动态SQL,然后创建临时表。我不确定他将如何实现它。他的方法必须灵活一些。他一直试图使用存储过程作为目前tsql不支持的表函数。 – 2013-04-30 09:23:44

0

一个非常好的参考:http://www.sommarskog.se/share_data.html

我设法从做部分地解决我的问题如下:

1)自定义存储过程来选择行集为一个全球性临时表 2)调用SP调用1),然后将## GlobalTempTable传输到本地#TempTable进行处理

这工作,但具有以下“问题”:

  • 潜在的安全风险,因为“即席分布式查询”功能,需要在
  • 被打开,仍然需要需要通过清理全局临时表呼叫者。临时表命名也是有问题的,因为多个2)会导致问题。

我在下面列出了我的代码以防别人帮助其他人。如果有人能够改进它,请随时发布。

/* This requires Adhoc Distributed Queries to be turned on: 
    sp_configure 'Show Advanced Options', 1 
    GO 
    RECONFIGURE 
    GO 
    sp_configure 'Ad Hoc Distributed Queries', 1 
    GO 
    RECONFIGURE 
    GO 
*/ 

-- Adapted from: http://stackoverflow.com/questions/653714/how-to-select-into-temp-table-from-stored-procedure 

CREATE PROCEDURE [dbo].[ExecIntoTable] 
(
    @tableName   NVARCHAR(256), 
    @storedProcWithParameters NVARCHAR(MAX) 
) 
AS 
BEGIN 
    DECLARE @driver   VARCHAR(10) 
    DECLARE @connectionString NVARCHAR(600) 
    DECLARE @sql   NVARCHAR(MAX) 
    DECLARE @rowsetSql  NVARCHAR(MAX) 

    SET @driver = '''SQLNCLI''' 

    SET @connectionString = 
     '''server=' + 
      CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(256)) + 
      COALESCE('\' + CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(256)), '') + 
     ';trusted_connection=yes;Database=' + DB_NAME() + '''' 

    SET @rowsetSql = '''EXEC ' + REPLACE(@storedProcWithParameters, '''', '''''') + '''' 



    SET @sql = ' 
SELECT 
    * 
INTO 
    ' + @tableName + ' 
FROM 
    OPENROWSET(' + @driver + ',' + @connectionString + ',' + @rowsetSql + ')' 

    EXEC (@sql) 
END 
GO 

然后在另一个SP使用如下:

EXEC ExecIntoTable '##MyGlobalTable', 'sp_MyStoredProc 13, 1' 
SELECT * 
INTO #MyLocalTable 
FROM ##MyGlobalTable 
DROP TABLE ##MyGlobalTable 

SELECT * FROM #MyLocalTable