Выбор всех данных, если строка пуста в операторе SQL IN - PullRequest
0 голосов
/ 12 июля 2020

У меня есть хранимая процедура для фильтров продуктов на моем веб-сайте, которая выглядит примерно так:

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_names будет @brand_names = ''.

Например, если пользователь выберет фирменное наименование Apple запрос должен возвращать все товары, относящиеся к этому бренду. И снова, если пользователь выбирает часы Type, запрос должен возвращать часы бренда Apple. Я использую SQL Server 2008.

Спасибо за помощь.

1 Ответ

3 голосов
/ 12 июля 2020

Для такого типа запроса «необязательный параметр» 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, как всегда, построит план для первого выполнения, а затем повторно использует этот план при последующих выполнениях. Это не очень хорошо, когда разные значения параметров могут так сильно повлиять на результат.

...