1

我正在使用 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 编译时间检查。
4

2 回答 2

1

您正在尝试使用像表格函数这样的过程。

尝试使用

INSERT INTO #MyTempTable (column1, column2...)
exec sp_ToBeCalled(@SomeOtherParam)
于 2013-04-29T22:27:32.177 回答
0

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

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

1) 自定义存储过程将 ROWSET 选择到全局临时表中 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
于 2013-04-30T23:38:43.623 回答