2013-04-29 88 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