使用SQL查询的复杂筛选条件

使用SQL查询的复杂筛选条件,sql,sql-server,tsql,Sql,Sql Server,Tsql,应用程序将5个不同的过滤条件从UI传递给查询。ie,-门店代码描述注释数量 当我用不同的可能性加上这些条件时,它会持续很长时间 --1 0 0 0 0 IF @Store<>'0' AND @code='' AND @DESC='' AND @Notes='' AND @QTY=0 --1 1 0 0 0 --1 1 0 0 1 --1 1 1 0 0 --1 1 1 1 0 etc.......... 有没有办法将其简

应用程序将5个不同的过滤条件从UI传递给查询。ie,-门店代码描述注释数量

当我用不同的可能性加上这些条件时,它会持续很长时间

--1 0   0   0   0
IF @Store<>'0' AND @code='' AND @DESC='' AND @Notes='' AND @QTY=0 
--1 1   0   0   0
--1 1   0   0   1
--1 1   1   0   0
--1 1   1   1   0
etc..........
有没有办法将其简化为单个查询。希望这个问题是可以理解的

下面是我做的示例代码

SET @sql = 'Select * from tbl_store Where Inactive=0 ';
--10000
    IF @Store<>'0' AND @Code='' AND @Description='' AND @Notes='' --AND @Qty<>''
    SET @sql += ' AND Store=@Store  AND Quantity = @Qty';

    --11000
    ELSE IF @Store<>'0' AND @Code<>'' AND @Description='' AND @Notes='' --AND @Qty<>''
    SET @sql += ' AND Store=@Store  AND Code=@Code  AND Quantity = @Qty';
一次做一个:

SET @sql = 'Select * from tbl_store Where Inactive = 0 ';
IF @Store <> '0' 
    SET @sql += ' and Store = @Store';
IF @Qty <> ''
    SET @sql += ' and Quantity = @Qty';
. . . .
一次做一个:

SET @sql = 'Select * from tbl_store Where Inactive = 0 ';
IF @Store <> '0' 
    SET @sql += ' and Store = @Store';
IF @Qty <> ''
    SET @sql += ' and Quantity = @Qty';
. . . .

我会将任何验证放在查询之外,并简单地按如下方式过滤您的查询

SET @IsValidFilter=<YOUR VALIDATION LOGIC HERE>--IF YOU CAN'T TRUST INCOMING VALUES

SELECT
    *
FROM
    MyTable
WHERE
    (@IsValidFilter=1)
    AND 
    (@Store IS NULL OR MyTable.StoreID=@Store) 
    AND 
    (@code= IS NULL OR MyTable.CodeID=@Code)
    AND
    (@DESC IS NULL OR MyTable.Description=@Desc)
    AND
    (@Notes IS NULL OR MyTable.Notes=@Notes)

如果您不能信任传入的值,并且需要一些基于参数值组合的逻辑,那么创建@ValidFilter标志并简单地添加final和@ValidFilter=1,而不是在WHERE中执行太多操作,会更具可读性。

我会将任何验证放在查询之外,并简单地根据需要筛选查询接着

SET @IsValidFilter=<YOUR VALIDATION LOGIC HERE>--IF YOU CAN'T TRUST INCOMING VALUES

SELECT
    *
FROM
    MyTable
WHERE
    (@IsValidFilter=1)
    AND 
    (@Store IS NULL OR MyTable.StoreID=@Store) 
    AND 
    (@code= IS NULL OR MyTable.CodeID=@Code)
    AND
    (@DESC IS NULL OR MyTable.Description=@Desc)
    AND
    (@Notes IS NULL OR MyTable.Notes=@Notes)

如果您不能信任传入的值,并且需要一些基于参数值组合的逻辑,那么创建@ValidFilter标志并简单地添加final和@ValidFilter=1将更具可读性,并且在WHERE中不做太多操作。

如果可能,我将取消动态查询,并执行以下操作:

select * 
from tbl_store ts
where ts.Inactive = 0
and (
    ( @Store <> '0' and @Description = '' and @Notes = '' and Store = @Store and Quantity = @Qty)
or
    (@Store <> '0' and @Code <> '' and @Notes <> '' and Code = @Code and Store = @Store and Quantity = @Qty)
);

使用动态查询(如您的查询)可能会导致安全漏洞,以及对如何进行操作的一般性混淆。在我看来,它应该是最后的手段之一。

如果可能的话,我会取消动态查询,并做如下操作:

select * 
from tbl_store ts
where ts.Inactive = 0
and (
    ( @Store <> '0' and @Description = '' and @Notes = '' and Store = @Store and Quantity = @Qty)
or
    (@Store <> '0' and @Code <> '' and @Notes <> '' and Code = @Code and Store = @Store and Quantity = @Qty)
);

使用动态查询(如您的查询)可能会导致安全漏洞,以及对如何进行操作的一般性混淆。在我看来,这应该是最后的选择之一。

很高兴我能帮忙。很高兴我能帮忙。