2011-02-03 33 views
16

Tôi có hai thủ tục được lưu trữ, một trong số đó trả về một danh sách các khoản thanh toán, trong khi phương thức kia trả về một bản tóm tắt các khoản thanh toán đó, được nhóm theo đơn vị tiền tệ. Ngay bây giờ, tôi có một truy vấn trùng lặp: truy vấn chính của thủ tục được lưu trữ trả về danh sách các khoản thanh toán là truy vấn phụ của thủ tục được lưu trữ trả về tóm tắt thanh toán bằng tiền tệ. Tôi muốn loại bỏ sự trùng lặp này bằng cách thực hiện thủ tục được lưu trữ trả về danh sách thanh toán truy vấn con của thủ tục được lưu trữ trả về tóm tắt thanh toán bằng tiền tệ. Điều đó có thể thực hiện được trong SQL Server 2008 không?Có thể sử dụng Thủ tục được lưu trữ làm truy vấn con trong SQL Server 2008 không?

Trả lời

15

Bạn nên chuyển đổi proc đầu tiên thành hàm TABLE-VALUED. Nếu nó liên quan đến nhiều câu lệnh, trước tiên bạn cần xác định cấu trúc bảng trả về và điền vào nó.

mẫu:

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

- trở thành -

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; 

Tuy nhiên, nếu đó là một lựa chọn thẳng (hoặc có thể được viết như một tuyên bố đơn), sau đó bạn có thể sử dụng INLINE dạng tvf, được tối ưu hóa cao

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 thứ hai chỉ đơn giản là chọn từ proc đầu tiên

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

Và nơi mà bạn sử dụng để gọi

EXEC firstProc @param 

để có được một kết quả, bây giờ bạn chọn từ nó

SELECT * FROM firstProc(@param) 
+0

Điều gì sẽ xảy ra khi thủ tục lưu trữ của bạn cần chạy OPENQUERY trên CUBE? Bạn không thể làm điều đó từ bên trong một hàm. –

6

Bạn có thể nắm bắt đầu ra từ một thủ tục được lưu trữ trong bảng tạm thời và sau đó sử dụng bảng trong truy vấn chính của bạn.

Ghi lại đầu ra của thủ tục được lưu trữ trả về cột ID và Tên thành biến bảng.

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

insert into @T 
exec StoredProcedure 
+0

Xin lỗi ... Bạn đã nói tạm thời *** FILE ***? Trong khi đó là một giải pháp khả thi về mặt kỹ thuật, tôi không nghĩ rằng tôi có thể đủ khả năng viết và xóa các tệp tạm thời khổng lồ. – pyon

+0

Bảng tạm thời, nó đã được sửa chữa trong câu trả lời nhưng chỉ muốn làm rõ cho độc giả trong tương lai có thể bị nhầm lẫn bởi các bình luận ở trên là lỗi thời. – Remi

3

Nếu bạn thực hiện thủ tục trả về danh sách vào hàm có giá trị bảng, thì tôi tin bạn có thể sử dụng nó trong truy vấn phụ.

6

Chèn kết quả của proc đã lưu vào bảng biến hoặc bảng tạm thời sẽ thực hiện thủ thuật.

Nếu bạn đang cố gắng sử dụng lại mã trong SQL Server từ truy vấn này sang truy vấn tiếp theo, bạn sẽ linh hoạt hơn với các hàm bảng. Lượt xem là tất cả các quyền nếu bạn không cần phải vượt qua các tham số hoặc sử dụng bất kỳ loại logic điều khiển luồng nào. Đây có thể được sử dụng như bảng trong bất kỳ chức năng khác, thủ tục, xem hoặc t-sql tuyên bố.

+0

Tôi đồng ý với Jeff. Bảng giá trị chức năng là rất tốt cho loại điều này. – brian

1

Tôi sẽ sử dụng một cái nhìn, trừ khi nó cần phải được tham số, trong trường hợp này, tôi sẽ sử dụng hàm có giá trị bảng nội tuyến nếu có thể, trừ khi nó cần phải là thao tác đa câu lệnh, nơi bạn vẫn có thể sử dụng hàm có giá trị bảng, nhưng chúng thường kém hiệu quả hơn.

+0

Tôi cần tham số để thực hiện cả hai truy vấn. Đây là lý do tại sao tôi đang sử dụng thủ tục được lưu trữ. – pyon

+0

@Eduardo Leon Tôi sẽ sử dụng một hàm bảng có giá trị nội tuyến nếu có thể. Chúng thực sự tương đương với các khung nhìn được tham số hóa về cách trình tối ưu hóa có thể xử lý chúng và kết hợp chúng với bất kỳ khung nhìn cơ bản nào và bất kỳ mã nào đang gọi ITVF. –

+0

Bạn có thể gọi ITVF trong mệnh đề 'FROM' của truy vấn không? – pyon

Các vấn đề liên quan