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

Selecting all data if the string is empty in SQL IN operator

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

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 函数将每个值从连接的字符串和 return 列表中分隔为 table。因此,当用户 select 品牌名称和类型查询 return 都是值但如果用户 select 仅品牌名称或类型时,查询不会 return任何事物。如果用户 select 品牌名称和类型或者不 select 任何一个,我想查询 return 产品(你知道每个电子商务网站都有过滤器).如果用户没有 select 任何过滤器,我将在变量中传递一个空字符串,如果用户没有 select 任何品牌,那么 @brand_names 将是 @brand_names = ''.

例如,如果用户 select Brand Name Apple,则查询必须 return 与该品牌相关的所有产品。同样,如果用户 select 手表类型,则查询必须 return Apple 品牌的手表。我正在使用 SQL Server 2008。

感谢您的帮助。

对于这种“可选参数”查询,在末尾添加一个option recompile可以提高性能。

如果“未选择”的参数是一个空字符串,那么您可以这样做:

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 ... 部分。如果您不这样做,那么 SQL 将一如既往地为第一次执行制定计划,然后在后续执行中重用该计划。当不同的参数值可以对结果产生如此大的差异时,这不是很好。