我的SQL Server 2005 DB中有一个通用存储过程
它会返回在网站上使用的产品项目列表,我希望在整个网站上使其更具可重用性,以便我可以使用它来返回特定数量的产品。
存储过程采用num items参数来限制返回的项目数量,但我想知道是否有一种方法可以让存储过程接受空值参数而不必诉诸维护两个select语句或2存储过程。
这是一个精简的示例,其中包含WHERE子句中的额外内容等。
create procedure GET_PRODUCTS
@num_items int = null
as
select TOP(@num_items) prod_id, prod_name, prod_price
from products
end
问题是我如何选择所有记录,就像在将null传递给proc的情况下顶部子句不存在一样。
我有几个想法,但我不确定它们在SQL Server方面的性能方面是如何规模的,这也是我想要评估的内容?
1)我可以检查param是否为null,如果是,则将其重新分配给一个非常大的整数,该整数应该大于表中的记录数量(目前约为5000并且正在增长)
2)与上述相同,但每次都计算产品表的大小
答案 0 :(得分:1)
使用IF
并创建两个查询:
create procedure GET_PRODUCTS
@num_items int = null
as
IF @num_items IS NULL
select prod_id,prod_name, prod_price from dbo.products
ELSE
select TOP(@num_items) prod_id,prod_name, prod_price from dbo.products
GO
也养成了总是使用表格模式(dbo
或其他)的习惯,它可以更好地重用查询计划。
答案 1 :(得分:1)
我认为你过度复杂了。如果你想要所有的行不告诉它要获取多少!只是做:
IF @Num_Items IS NULL
BEGIN
SELECT prod_id,prod_name, prod_price from products
END
ELSE
<Your existing code>
修改强>
如果您绝对想要使用TOP
子句,只需将其指定为非常高的值2147483647
即可。这是int
数据类型的最高可能值。查询分析器不会尝试返回那么多行,但它会确保它不会返回 MORE 而不是您指定的行,并且它根本不会影响性能。
答案 2 :(得分:0)
您可以使用动态查询:
create procedure GET_PRODUCTS
@num_items int = null
as
declare @sql nvarchar(max)
set @sql = N'select '
if @num_items is not null
set @sql = @sql + 'TOP(@num_items) '
set @sql = @sql + 'prod_id,prod_name, prod_price from products'
execute sp_executesql @sql
,N'@num_items int = null'
,@num_items
end
答案 3 :(得分:0)
你可以做到
select TOP(@num_items) prod_id, prod_name, prod_price
from products where @num_items is not null
union
select prod_id, prod_name, prod_price
from products where @num_items is null
或者你可以
select TOP(isnull(@num_items,Very large number)) prod_id, prod_name, prod_price
from products