假设我在存储过程中有一个参数@Name
。如果它不是空/ null,我想通过此参数仅进行过滤。在任何其他情况下,我想忽略过滤器。
我提出了以下两种解决方案。为了举例,我们只考虑参数为空的情况。
select *
from MyTable
where (len(rtrim(ltrim(@Name))) > 0 and Name = @Name) or (len(rtrim(ltrim(@Name))) = 0)
和第二个
@query = 'select * from MyTable'
if (len(rtrim(ltrim(@Name))) > 0)
@query = @query + ' Name = @Name '
这两种方法都按预期工作。
注意:此问题也可能适用于代码审核,如果您愿意,请发表评论,以便迁移到那里
答案 0 :(得分:3)
可以像这样简化
select *
from MyTable
where Name = @Name or @Name = '' or @Name is null
或如评论中所述,使用NULLIF
检查空字符串,然后将其替换为NULL
,然后针对IS NULL
where (Name = @Name or nullif(@Name, '') is null)
答案 1 :(得分:1)
你不需要检查长度,默认情况下,sql server是trailing-spaces-sensitive(这个规则的唯一例外是当LIKE谓词表达式的右侧包含尾随空格时,然后垫没有被移除)。
请使用以下代码。
DECLARE @Name=' '
IF(@Name='') SELECT 1 ELSE SELECT 0
如果你运行上面的代码,你会得到1的结果。在你的情况下,你可以放弃LTRIM和RTRIM,只测试空字符串文字的相等性。
select *
from MyTable
where ((@Name='' OR @Name IS NULL)OR(Name = @Name))
OR
IF(@Name='') SET @Name=NULL
select *
from MyTable
where (@Name IS NULL OR Name = @Name)
答案 2 :(得分:0)
如果你在存储过程中使用动态sql尝试这样的事情。最好为主选择查询和动态使用不同的变量,其中查询可以很容易地扩展。使用这种方法,当你的过程变得冗长时,它很容易维护。
declare @finalquery varchar(max)
declare @mainSelectquery nvarchar(500);
declare @whereCondtions varchar (1000);
declare @DateParam datetime
set @mainSelectquery=''
set @whereCondtions =''
set @finalquery =''
set @DateParam=getdate()
set @mainSelectquery = 'select * from tblOrders where 1=1 '
set @whereCondtions = ' and Order_site =''TSN'''
set @whereCondtions = @whereCondtions + ' AND CAST(ORDER_APPROVED_DATE_LT AS DATE)=CAST(GETDATE() AS DATE)'
set @finalquery =( @mainSelectquery + @whereCondtions)
print @finalquery
---- You can further extend this by adding more where condition based on the parameter pass in stored proc
if (@OrderID !=0)
begin
set @whereCondtions = ' OrderID='+str ( @stateRefID )
end