【发布时间】:2011-02-03 17:40:32
【问题描述】:
我有两个存储过程,其中一个返回付款列表,而另一个返回这些付款的摘要,按货币分组。现在,我有一个重复的查询:返回付款列表的存储过程的主查询是返回按货币支付的摘要的存储过程的子查询。我想通过使返回支付列表的存储过程成为返回按货币支付的摘要的存储过程的子查询来消除这种重复性。这在 SQL Server 2008 中是否可行?
【问题讨论】:
标签: sql-server stored-procedures subquery
我有两个存储过程,其中一个返回付款列表,而另一个返回这些付款的摘要,按货币分组。现在,我有一个重复的查询:返回付款列表的存储过程的主查询是返回按货币支付的摘要的存储过程的子查询。我想通过使返回支付列表的存储过程成为返回按货币支付的摘要的存储过程的子查询来消除这种重复性。这在 SQL Server 2008 中是否可行?
【问题讨论】:
标签: sql-server stored-procedures subquery
最好将第一个 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;
但是如果是直接选择(或者可以写成单条语句),那么可以使用高度优化的INLINE 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
第二个过程只是从第一个过程中选择
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)
【讨论】:
您可以在临时表中捕获存储过程的输出,然后在主查询中使用该表。
捕获将列 ID 和名称返回到表变量的存储过程的输出。
declare @T table (ID int, Name nvarchar(50))
insert into @T
exec StoredProcedure
【讨论】:
EXEC INTO #tmp :-)
将存储过程的结果插入到表变量或临时表中即可。
如果您尝试将 SQL Server 中的代码从一个查询重复使用到下一个查询,则可以使用表函数获得更大的灵活性。如果您不需要传递参数或使用任何类型的流控制逻辑,视图就可以了。这些可以像任何其他函数、过程、视图或 t-sql 语句中的表一样使用。
【讨论】:
如果您将返回列表的过程设为表值函数,那么我相信您可以在子查询中使用它。
【讨论】:
我会使用视图,除非它需要参数化,在这种情况下,如果可能的话,我会使用内联表值函数,除非它需要是多语句操作,你仍然可以使用表-值函数,但它们通常效率较低。
【讨论】:
FROM 子句中调用 ITVF 吗?