SQL alter where子句中的筛选器数
有时我需要改变WHERE子句中过滤器的数量,我正在寻找最好的建议。 下面是一个场景: 表1(Col1、Col2、Col3)SQL alter where子句中的筛选器数,sql,sql-server,tsql,stored-procedures,where,Sql,Sql Server,Tsql,Stored Procedures,Where,有时我需要改变WHERE子句中过滤器的数量,我正在寻找最好的建议。 下面是一个场景: 表1(Col1、Col2、Col3) Col1包含唯一的id。 Col2包含数字0到1000,非唯一。 Col3包含字母表A到Z的非唯一字母 我有一个StoredProc1,它只接受一个参数,但根据参数的值,它应该只搜索Col2,或者同时搜索Col2和Col3。查看1列或2列的决定是任意的,需要对存储过程进行性能优化 下面的代码正在执行此任务,但非常难以管理。我有一个存储过程,以这种方式包含128个不同的分支,
Col1包含唯一的id。
Col2包含数字0到1000,非唯一。
Col3包含字母表A到Z的非唯一字母 我有一个StoredProc1,它只接受一个参数,但根据参数的值,它应该只搜索Col2,或者同时搜索Col2和Col3。查看1列或2列的决定是任意的,需要对存储过程进行性能优化 下面的代码正在执行此任务,但非常难以管理。我有一个存储过程,以这种方式包含128个不同的分支,如果我再添加一个条件,它将构成另外128个分支,总共6000行代码。一定有更好的办法 我正在考虑声明另一个变量,并将其设置为默认值,该值始终为不匹配。然后根据StoredProc1参数中传递的值,将第二个变量设置为相关值。此解决方案的问题在于,如果第二个筛选器不适用,则会降低搜索性能。 我无法更改StoredProc1定义,因为它被无数其他进程调用。 到目前为止,我唯一想到的是创建另一个SP,如果条件为真,则从主SP调用它,并保持当前proc为else分支
StoredProc1 ( @filter ) as
begin
if (@filter = 1)
begin
select col1, col2, col3
from Table1
where Col2 = @filter or Col2 = 'A'
end
else
begin
select Col1, Col2, Col3
from Table1
where Col2 = @Filter
end
end
在某些情况下,您可以使用以下内容:
declare @iFilterCol1 int;
declare @iFilterCol2 int;
declare @iFilterCol3 varchar(100);
set @iFilterCol1 = 5;
set @iFilterCol2 = 100;
set @iFilterCol3 = 'aaa';
select col1, col2, col3
from Table1
where
(Col1 = case when @iFilterCol1 is not null then @iFilterCol1 else Col1 end)
and (Col2 = case when @iFilterCol2 is not null then @iFilterCol2 else Col2 end)
and (Col3 = case when @iFilterCol3 is not null then @iFilterCol3 else Col3 end);
在这种情况下,当您将值赋给@iFilterCol1时,您将按Col1进行过滤,否则将跳过它。其他两列也一样。考虑到我使用了
和。Yuo可以使用或
,但两者的组合取决于您要应用的过滤器,在某些情况下不可能。在某些情况下,您可以使用类似于:
declare @iFilterCol1 int;
declare @iFilterCol2 int;
declare @iFilterCol3 varchar(100);
set @iFilterCol1 = 5;
set @iFilterCol2 = 100;
set @iFilterCol3 = 'aaa';
select col1, col2, col3
from Table1
where
(Col1 = case when @iFilterCol1 is not null then @iFilterCol1 else Col1 end)
and (Col2 = case when @iFilterCol2 is not null then @iFilterCol2 else Col2 end)
and (Col3 = case when @iFilterCol3 is not null then @iFilterCol3 else Col3 end);
StoredProc1
@filter DataType
as
begin
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N'select Col1, Col2, Col3
from Table1 WHERE 1 = 1 '
+ CASE WHEN @filter = 1 THEN N' AND Col2 = @Param or Col2 = ''A'''
ELSE N' AND Col2 = @Filter' END
EXECUTE sp_executesql @Sql
, N'DECLARE @Param DataType'
, @Param = @filter
end
在这种情况下,当您将值赋给@iFilterCol1时,您将按Col1进行过滤,否则将跳过它。其他两列也一样。考虑到我使用了和。Yuo可以使用或
,但两者的组合取决于您要应用的过滤器,在某些情况下不可能。在某些情况下,您可以使用类似于:
declare @iFilterCol1 int;
declare @iFilterCol2 int;
declare @iFilterCol3 varchar(100);
set @iFilterCol1 = 5;
set @iFilterCol2 = 100;
set @iFilterCol3 = 'aaa';
select col1, col2, col3
from Table1
where
(Col1 = case when @iFilterCol1 is not null then @iFilterCol1 else Col1 end)
and (Col2 = case when @iFilterCol2 is not null then @iFilterCol2 else Col2 end)
and (Col3 = case when @iFilterCol3 is not null then @iFilterCol3 else Col3 end);
StoredProc1
@filter DataType
as
begin
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N'select Col1, Col2, Col3
from Table1 WHERE 1 = 1 '
+ CASE WHEN @filter = 1 THEN N' AND Col2 = @Param or Col2 = ''A'''
ELSE N' AND Col2 = @Filter' END
EXECUTE sp_executesql @Sql
, N'DECLARE @Param DataType'
, @Param = @filter
end
在这种情况下,当您将值赋给@iFilterCol1时,您将按Col1进行过滤,否则将跳过它。其他两列也一样。考虑到我使用了和。Yuo可以使用或
,但两者的组合取决于您要应用的过滤器,在某些情况下不可能。在某些情况下,您可以使用类似于:
declare @iFilterCol1 int;
declare @iFilterCol2 int;
declare @iFilterCol3 varchar(100);
set @iFilterCol1 = 5;
set @iFilterCol2 = 100;
set @iFilterCol3 = 'aaa';
select col1, col2, col3
from Table1
where
(Col1 = case when @iFilterCol1 is not null then @iFilterCol1 else Col1 end)
and (Col2 = case when @iFilterCol2 is not null then @iFilterCol2 else Col2 end)
and (Col3 = case when @iFilterCol3 is not null then @iFilterCol3 else Col3 end);
StoredProc1
@filter DataType
as
begin
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N'select Col1, Col2, Col3
from Table1 WHERE 1 = 1 '
+ CASE WHEN @filter = 1 THEN N' AND Col2 = @Param or Col2 = ''A'''
ELSE N' AND Col2 = @Filter' END
EXECUTE sp_executesql @Sql
, N'DECLARE @Param DataType'
, @Param = @filter
end
在这种情况下,当您将值赋给@iFilterCol1时,您将按Col1进行过滤,否则将跳过它。其他两列也一样。考虑到我使用了和。you可以使用或
,但两者的组合取决于要应用的过滤器,在某些情况下不可能
StoredProc1
@filter DataType
as
begin
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N'select Col1, Col2, Col3
from Table1 WHERE 1 = 1 '
+ CASE WHEN @filter = 1 THEN N' AND Col2 = @Param or Col2 = ''A'''
ELSE N' AND Col2 = @Filter' END
EXECUTE sp_executesql @Sql
, N'DECLARE @Param DataType'
, @Param = @filter
end
您可以使用多个Case语句来检查多个参数,并生成sql字符串。
更灵活、更安全的操作方式
StoredProc1 ( @filter ) as
begin
select col1, col2, col3
from Table1
where Col2 = @filter or (@filter = '1' and Col2 = 'A')
end
您可以使用多个Case语句来检查多个参数,并生成sql字符串。
更灵活、更安全的操作方式
StoredProc1 ( @filter ) as
begin
select col1, col2, col3
from Table1
where Col2 = @filter or (@filter = '1' and Col2 = 'A')
end
您可以使用多个Case语句来检查多个参数,并生成sql字符串。
更灵活、更安全的操作方式
StoredProc1 ( @filter ) as
begin
select col1, col2, col3
from Table1
where Col2 = @filter or (@filter = '1' and Col2 = 'A')
end
您可以使用多个Case语句来检查多个参数,并生成sql字符串。
更灵活、更安全的操作方式
StoredProc1 ( @filter ) as
begin
select col1, col2, col3
from Table1
where Col2 = @filter or (@filter = '1' and Col2 = 'A')
end
无论您选择什么解决方案,都将失去性能。每次都可能需要编译动态SQL。您的“分支”方法运行良好
无论您选择什么解决方案,都将失去性能。每次都可能需要编译动态SQL。您的“分支”方法运行良好
无论您选择什么解决方案,都将失去性能。每次都可能需要编译动态SQL。您的“分支”方法运行良好
无论您选择什么解决方案,都将失去性能。每次都可能需要编译动态SQL。您的“分支”方法运行良好 动态SQL是您的朋友。请提供输入参数的完整列表。例如Col1FilterPresent,Col1FilterPresent。。。Col1FulterValue。我认为有一种方法(虽然不确定),但我需要输入参数。此外,您还需要使用AND或as或?Erland Sommarskog的@filter是整数还是varchar?动态SQL是您的朋友请提供输入参数的完整列表。例如Col1FilterPresent,Col1FilterPresent。。。Col1FulterValue。我认为有一种方法(虽然不确定),但我需要输入参数。此外,您还需要使用AND或as或?Erland Sommarskog的@filter是整数还是varchar?动态SQL是您的朋友请提供输入参数的完整列表。例如Col1FilterPresent,Col1FilterPresent。。。Col1FulterValue。我认为有一种方法(虽然不确定),但我需要输入参数。此外,您还需要使用AND或as或?Erland Sommarskog的@filter是整数还是varchar?动态SQL是您的朋友请提供输入参数的完整列表。例如Col1FilterPresent,Col1FilterPresent。。。Col1FulterValue。我认为有一种方法(虽然不确定),但我需要输入参数。你也需要像AND或as或?Erland Sommarskog的@filter是整数还是varchar?这正是我想要的。我不知道你们是否能在WHERE子句中插入CASE。您认为此选项会带来高性能的损失吗?@user2611947-如果结果sql语句中的Where子句不包含CASE语句,则它只包含在字符串concate中