无法将存储过程的结果转换为#TempTable才能工作

时间:2013-04-29 21:41:51

标签: sql-server-2008 tsql

我正在使用SQL Server 2008 R2并尝试将存储过程的结果放入临时表中,稍后我可以在调用存储过程中访问该表。我的TSQL如下:

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编译时检查。

2 个答案:

答案 0 :(得分:1)

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

尝试使用

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

答案 1 :(得分:0)

一个很棒的参考:http://www.sommarskog.se/share_data.html

我设法通过执行以下操作来部分解决我的问题:

1)自定义存储过程,用于选择ROWSET到全局临时表中 2)调用SP调用1)然后将## GlobalTempTable传输到本地#TempTable进行处理

这有效,但有以下“问题”:

  • 需要启用“Adhoc Distributed Queries”功能的潜在安全风险
  • 仍然需要呼叫者需要清理的全局临时表。临时表命名也存在问题,因为多个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