Хранимая процедура игнорирует пустые значения и получает результат только для введенных параметров - PullRequest
0 голосов
/ 18 марта 2020

Я создаю хранимую процедуру для поиска в таблице. У меня есть много разных столбцов поиска, все из которых являются необязательными. Есть ли способ создать хранимую процедуру, которая будет обрабатывать это? Допустим, у меня есть таблица с четырьмя столбцами ID, N1, N2 и N3. Я мог бы сделать что-то вроде этого:

Таблица:

INSERT INTO [dbo].[Sample]
VALUES ('1', 'A,B,C', 'A,B,C', 'A,B,C'),
       ('2', 'B,D,N', 'B,D,N', 'B,D,N'),
       ('3', 'A,N,S', 'A,N,S', 'A,N,S'),
       ('4', 'S,F,G', 'S,F,G', 'S,F,G'),
       ('5', 'D,F,K', 'D,F,K', 'D,F,K'),
       ('6', 'S,H,Y', 'S,H,Y', 'S,H,Y'),
       ('7', 'Z,B,C', 'Z,B,C', 'Z,B,C')

Хранимая процедура:

CREATE PROCEDURE dbo.Sample2
    @n11 varchar(max) = null,  
    @n12 varchar(max) = null,
    @n21 varchar(max) = null,
    @n22 varchar(max) = null,
    @n31 varchar(max) = null,
    @n32 varchar(max) = null
AS        
BEGIN      
    SELECT COUNT(*) 
    FROM Sample
    WHERE 
        (@n11 IS NULL OR Sample.N1 LIKE '%' + @n11 + '%' 
         OR @n12 IS NULL OR Sample.N1 LIKE '%' + @n12 + '%')
        AND (@n21 IS NULL OR Sample.N2 LIKE '%' + @n21 + '%' 
             OR @n22 IS NULL OR Sample.N2 LIKE '%' + @n22 + '%')
        AND (@n31 IS NULL OR Sample.N3 LIKE '%' + @n31 + '%' 
             OR @n32 IS NULL OR Sample.N3 LIKE '%' + @n32 + '%')
END

Если пользователь вводит @ n11 как A и оставляет остальные, так как N1 содержит A в 2 строках, вывод должен быть 2, но вышеупомянутый запрос предоставляет 7. Если параметр не указан, мне нужно его игнорировать и передать остаток в условие where.

Ответы [ 3 ]

1 голос
/ 18 марта 2020

Я думаю, вам нужно AND каждое отдельное условие ввода, например,

SELECT count(*)
FROM [Sample] S
WHERE (@n11 IS NULL OR S.N1 LIKE '%'+@n11+'%')
AND (@n12 IS NULL OR S.N1 LIKE '%'+@n12+'%')
AND (@n21 IS NULL OR S.N2 LIKE '%'+@n21+'%')
AND (@n22 IS NULL OR S.N2 LIKE '%'+@n22+'%')
AND (@n31 IS NULL OR S.N3 LIKE '%'+@n31+'%')
AND (@n32 IS NULL OR S.N3 LIKE '%'+@n32+'%')

Обратите внимание на псевдоним, который является лучшим способом избежать необходимости повторять длинное имя таблицы во всем запросе.

0 голосов
/ 18 марта 2020
select
  sum(iif(N1 like '%'+@N11+'%',1,0)  
    + iif(N1 like '%'+@N12+'%',1,0) 
    + iif(N2 like '%'+@N21+'%',1,0) 
    + iif(N2 like '%'+@N22+'%',1,0) 
    + iif(N3 like '%'+@N31+'%',1,0) 
    + iif(N3 like '%'+@N32+'%',1,0) 
  )
from Sample

Любые NULL переменные будут игнорироваться.

0 голосов
/ 18 марта 2020

Попробуйте удалить следующие условия из запроса вашей хранимой процедуры:

@n12 IS NULL
@n22 IS NULL
@n32 IS NULL

Поскольку приведенные выше условия возвращаются всегда, true пока были отправлены при вызове процедуры.

Код хранимой процедуры после изменения:

Alter Procedure dbo.Sample2
  @n11 varchar(max) = null,  
  @n12 varchar(max) = null,
  @n21 varchar(max) = null,
  @n22 varchar(max) = null,
  @n31 varchar(max) = null,
  @n32 varchar(max) = null
AS        
BEGIN      
  select count(*)
  from Sample
  where (@n11 IS NULL OR Sample.N1 LIKE '%'+@n11+'%' OR Sample.N1 LIKE '%'+@n12+'%')
  AND (@n21 IS NULL OR Sample.N2 LIKE '%'+@n21+'%' OR Sample.N2 LIKE '%'+@n22+'%')
  AND (@n31 IS NULL OR Sample.N3 LIKE '%'+@n31+'%' OR Sample.N3 LIKE '%'+@n32+'%')
END

Теперь при выполнении exec dbo.Sample2 @n11 = 'A' вывод будет 2 вместо 7

...