2009-09-18 58 views
12
CREATE PROCEDURE [test].[proc] 
@ConfiguredContentId int, 
@NumberOfGames int 
AS 
BEGIN 
SET NOCOUNT ON 
RETURN 
@WunNumbers TABLE (WinNumb int) 

    INSERT INTO @WunNumbers (WinNumb) 
SELECT TOP (@NumberOfGames) WinningNumber 
FROM [Game].[Game] g 
JOIN [Game].[RouletteResult] AS rr ON g.[Id] = rr.[gameId] 
WHERE g.[ConfiguredContentId] = @ConfiguredContentId 
ORDER BY g.[Stoptime] DESC 

SELECT WinNumb, COUNT (WinNumb) AS "Count" 
FROM @WunNumbers wn 
GROUP BY wn.[WinNumb] 
END 
GO 

該存儲過程返回第一個select語句的值,但我想要從第二個select語句返回值。表@WunNumbers是一個臨時表。如何從存儲過程返回臨時表

任何想法???

+0

請重新格式化您的sql代碼。 – 2009-09-18 10:22:22

+0

該代碼不是有效的SQL。這可能是,如果「RETURN @WinNumbers」是「DECLARE @WinNumbers」,但其餘部分看起來是正確的返回我現在看到的最終結果集 – 2009-09-18 10:35:37

+0

,我發佈了錯誤的代碼。有「DECLARE @WinNumbers」,但它仍然不起作用。 – dani 2009-09-18 10:46:49

回答

6

您使用的是哪個版本的SQL Server?在SQL Server 2008中,您可以使用Table Parameters and Table Types

另一種方法是從用戶定義函數返回表變量,但我不是這種方法的忠實粉絲。

你可以找到一個例子here

+0

我正在使用sql server 2005 – dani 2009-09-18 10:43:07

25

這個代碼看看,

CREATE PROCEDURE Test 

AS 
    DECLARE @tab table (no int, name varchar(30)) 

    insert @tab select eno,ename from emp 

    select * from @tab 
RETURN 
+0

這將如何返回/輸出一個表變量給調用者?它目前返回一個結果集。 – 2009-09-18 10:53:43

+3

它返回select語句(實際問題)的結果,在這種情況下,恰好是本地表變量@tab的內容。 – JeffO 2009-09-18 13:56:54

+5

如果我執行'EXECUTE測試'我如何訪問@tab? – whytheq 2012-08-07 15:41:05

0

過程的返回類型爲int。

您也可以返回結果集(如你的代碼目前確實)(好吧,你也可以發送郵件,這是字符串)

這些都是唯一的「返回」你可以做到的。雖然可以將表值參數添加到過程(請參閱BOL),但它們只是輸入。

編輯:

(或作爲另一個海報所說,你也可以使用一個表值函數,而不是一個過程)

2

一個臨時表可以在調用者創建,然後從填充被稱爲SP。

create table #GetValuesOutputTable(
    ... 
); 

    exec GetValues; -- populates #GetValuesOutputTable 

    select * from #GetValuesOutputTable; 

這種方法比「insert exec」的一些優點是它可以嵌套並且可以用作輸入或輸出。

一些缺點是「參數」不是公共的,表的創建存在於每個調用者中,並且表的名稱可能與其他臨時對象相沖突。它有助於臨時表名稱與SP名稱緊密匹配並遵循一些約定。

進一步說,對於只輸出臨時表,insert-exec方法和臨時表方法可以被稱爲SP同時支持。這對於鏈接SP來說並沒有多大幫助,因爲該表仍然需要在調用者中定義,但可以幫助簡化cmd行的測試或在外部調用時。

-- The "called" SP 
    declare 
     @returnAsSelect bit = 0; 

    if object_id('tempdb..#GetValuesOutputTable') is null 
    begin 
     set @returnAsSelect = 1; 
     create table #GetValuesOutputTable(
     ... 
    ); 
    end 

    -- populate the table 

    if @returnAsSelect = 1 
     select * from #GetValuesOutputTable; 
0

是的你可以。

在您的存儲過程中,填寫表@tbRetour

在這個存儲過程的最後,你寫的:

SELECT * FROM @tbRetour 

要執行存儲過程,你寫的:

USE [...] 
GO 

DECLARE @return_value int 

EXEC @return_value = [dbo].[getEnregistrementWithDetails] 
@id_enregistrement_entete = '(guid)' 

GO 
0

首先創建一個真正的,永久的表作爲模板具有返回的臨時表所需的佈局,使用命名約定將其標識爲模板並將其按符號鏈接到SP,例如tmp_SPName_Output。這張表不會包含任何數據。

在SP中,按照相同的命名約定,使用INSERT將數據加載到臨時表中。 #SPName_Output假設存在。你可以測試它的存在,如果不存在就返回一個錯誤。

之前調用SP利用這個簡單的選擇創建臨時表:

SELECT TOP(0) * INTO #SPName_Output FROM tmp_SPName_Output; 
EXEC SPName; 
-- Now process records in #SPName_Output; 

這具有以下獨特的優勢:

  • 的臨時表是本地到當前會話,不像## ,因此不會與來自 不同會話的SP併發呼叫衝突。超出範圍時它也會自動丟棄。
  • 模板表與SP保持一致,因此如果對輸出進行的更改是 (例如添加了新列),則SP的預先存在的 呼叫者不會中斷。來電者不需要改變。
  • 您可以定義任意數量的輸出表,命名爲 一個SP,並填充全部。您還可以定義具有不同命名的替代輸出 ,並讓SP檢查臨時表 的存在以查看哪些需要填充。
  • 同樣,如果進行了重大更改但希望保持向後兼容性,則可以爲後面的 版本創建一個新的模板表和命​​名,但仍然支持早期版本,方法是檢查調用程序創建哪個表 表。