2011-02-03 62 views
16

我有兩個存儲過程,其中一個返回支付列表,另一個返回按貨幣分組的支付摘要。現在,我有一個重複的查詢:返回支付列表的存儲過程的主要查詢是存儲過程的子查詢,該查詢返回貨幣支付概要。我想通過使返回付款清單的存儲過程成爲存儲過程的子查詢來消除這種重複性,該過程通過貨幣返回付款摘要。在SQL Server 2008中可能嗎?是否可以在SQL Server 2008中使用存儲過程作爲子查詢?

回答

15

您最好將第一個proc轉換爲TABLE-VALUED函數。如果它涉及多個語句,則需要先定義返回表結構並填充它。

樣品:

CREATE proc getRecords @t char(1) 
as 
set nocouut on; 
-- other statements -- 
-- final select 
select * from master..spt_values where type = @t 
GO 

- 變 -

CREATE FUNCTION fn_getRecords(@t char(1)) 
returns @output table(
    name sysname, 
    number int, 
    type char(1), 
    low int, 
    high int, 
    status int) as 
begin 
-- other statements -- 
-- final select 
insert @output 
select * from master..spt_values where type = @t 
return 
end; 

但是,如果是直的選擇(或者可以寫成一個單獨的語句),那麼你可以使用內聯tvf形式,高度優化

CREATE FUNCTION fn2_getRecords(@t char(1)) 
returns table as return 
-- **NO** other statements; single statement table -- 
select * from master..spt_values where type = @t 

第二個proc只是從第一個proc中選擇

create proc getRecordsByStatus @t char(1) 
as 
select status, COUNT(*) CountRows from dbo.fn2_getRecords(@t) 
group by status 

你在哪裏用來調用

EXEC firstProc @param 

得到一個結果,你現在選擇它

SELECT * FROM firstProc(@param) 
+0

當存儲過程需要在多維數據集上運行OPENQUERY時會發生什麼?你不能在一個函數內做到這一點。 – 2014-01-31 15:31:57

6

您可以捕獲臨時表中存儲過程的輸出,然後在主查詢中使用該表。

捕獲存儲過程的輸出,將列ID和名稱返回給表變量。

declare @T table (ID int, Name nvarchar(50)) 

insert into @T 
exec StoredProcedure 
+0

不好意思......你說過臨時***文件***嗎?雖然從技術上來說這是一個可行的解決方案,但我認爲我無法一直寫下和刪除大量臨時文件。 – pyon 2011-02-03 17:46:50

+0

臨時表,它在答案中得到糾正,但只是想澄清未來的讀者可能會因上述評論過時而感到困惑。 – Remi 2017-03-29 08:46:27

3

如果您製作了將列表返回到表值函數的過程,那麼我相信您可以在子查詢中使用它。

6

將存儲過程的結果插入到表變量或臨時表中會起到一定作用。

如果您試圖在SQL Server中將代碼從一個查詢重用到下一個查詢,那麼您可以更靈活地使用表函數。如果您不需要傳遞參數或使用任何類型的流量控制邏輯,那麼視圖是正確的。這些可以像任何其他函數,過程,視圖或t-sql語句中的表一樣使用。

+0

我同意傑夫。表值函數對於這類事情很好。 – brian 2011-02-03 20:18:34

1

我會用一個視圖,除非它需要的參數,在這種情況下,如果可能的話,我會使用內聯表值函數,除非它需要是多語句操作,您仍然可以使用表值函數,但通常效率較低。

相關問題