如果sql in运算符中的字符串为空,则选择所有数据

wrrgggsh  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(501)

我在我的网站上有一个产品过滤器的存储过程,如下所示:

ALTER PROCEDURE [dbo].[sp_product_get_by_filters]
    (@brand_names nvarchar(max),
     @type nvarchar(max))
AS
BEGIN
    SELECT     
        tbl_product.product_code, 
        tbl_product.brand_name, 
        tbl_product.subcategory_code, 
        tbl_product.product_name, 
        tbl_product.product_photo_1,
        tbl_product.filter_code, 
        (select filter_name from tbl_filter where filter_code =  tbl_product.filter_code )as filter_name,
        (select AVG(CAST(rating AS DECIMAL(10,2))) from tbl_review where product_code = tbl_product.product_code) as Rating,
        (select TOP 1 sub_product_price from tbl_sub_product where product_code = tbl_product.product_code) as product_price,
        (select TOP 1 size from tbl_sub_product where product_code = tbl_product.product_code) as size,
        (select TOP 1 sub_product_code from tbl_sub_product where  product_code = tbl_product.product_code) as sub_product_code
    FROM  
        tbl_product 
    WHERE 
        tbl_product.brand_name IN (SELECT * FROM dbo.splitstring(@brand_names)) 
        AND tbl_product.filter_code IN (SELECT * FROM dbo.splitstring(@type)) 
END
``` `@brand_names` 例如,这里有一个用逗号分隔的品牌名称字符串

Apple,Samsung,Nokia

以及 `@type` 产品的过滤器是什么样的

'Watch,Mobile,Tablet'

这个 `dbo.splitstring` 函数将每个值从连接的字符串中分离出来,并将列表作为表返回。因此,当用户同时选择brand name和type时,查询会返回值,但如果用户只选择brand name或type,查询不会返回任何值。如果用户同时选择了品牌名称和类型,或者没有选择其中任何一个(你知道,就像每个电子商务网站中的过滤器一样),我想进行查询以返回产品。如果用户没有选择任何过滤器,我将在变量中传递一个空字符串,比如如果用户没有选择任何品牌,那么@brand\u names将是 `@brand_names = ''` .
例如,如果用户选择品牌名称apple,则查询必须返回与该品牌相关的所有产品。同样,如果用户选择watch类型,那么查询必须返回apple品牌的手表。我使用的是sql server 2008。
谢谢你的帮助。
cngwdvgl

cngwdvgl1#

对于这种“可选参数”查询 option recompile 最终可以提高相当多的性能。
如果“unselected”参数是空字符串,则可以执行以下操作:

WHERE 
   (@brand_names = '' or tbl_product.brand_name IN (SELECT * from dbo.splitstring(@brand_names)))
   and (@type = '' or tbl_product.filter_code IN (SELECT * from dbo.splitstring(@type)))
option (recompile)

这个 option (recompile) 告诉sql每次运行过程时都为此语句生成新计划。例如,如果你给 @brand_names ,引擎甚至不需要评估 or tbl_product.brand_name in ... 这是 predicate 的一部分。如果不这样做,那么sql将一如既往地为第一次执行构建一个计划,然后在后续执行中重用该计划。当不同的参数值可以对结果产生如此大的差异时,这不是很好。

相关问题