【问题标题】:Cannot get results of a stored procedure into a #TempTable to work [duplicate]无法将存储过程的结果放入#TempTable 中以正常工作[重复]
【发布时间】:2013-04-23 17:08:30
【问题描述】:

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

【问题讨论】:

标签: sql-server-2008 tsql


【解决方案1】:

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

尝试使用

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

【讨论】:

  • OP 不想在填充临时表之前定义它的结构。
  • 所以省略列列表?
  • @Gilm:“TheEdge”期待提出一个解决方案,他不必更改存储过程,也不必使用动态 sql,然后动态创建临时表。我们不确定他将如何实现这一目标。他的方法必须有点灵活。他一直在尝试使用存储过程作为表函数,目前 tsql 不支持。
  • @ElectricLlama:抱歉,我无法理解您的评论。您在这里指的是哪一列?
  • 对不起,我的错误,我以为你可以在没有列列表的情况下使用INSERT INTO,但你不能。
【解决方案2】:

一个很好的参考: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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 2015-07-19
    • 1970-01-01
    相关资源
    最近更新 更多