SQL Server, преобразование механизма выбора из «и» в «или» - PullRequest
0 голосов
/ 08 июля 2010

У меня есть веб-программа, которая выбирает некоторые записи из базы данных, используя флажок. (мой список флажков отправляет параметры хранимой процедуре, и я использую результат хранимой процедуры).

Вот как выглядит мой список флажков

Overflow              [] (sends param1)
Open Records          [] (sends param2)
Records with 4 groups [] (sends param3)

Вот как выглядит моя хранимая процедура,

SELECT * FROM myRecordsTable WHERE
        (Overflow LIKE '%O%' OR @param1= 'No')
        AND (OpenClose= 'Open' OR @param2= 'No')
        AND (4orMore = '4orMore' OR @param3 = 'No')

Итак, как вы можете видеть, мои списки флажков работают подобно процедуре "И", другими словами, когда я проверяю Переполнение и Открывать записи в моем списке флажков, моя хранимая процедура возвращает ( Открытые записи , имеет переполнение )

Что мне нравится делать, так это то, что я хочу, чтобы мой список флажков работал как «Или», другими словами, я хочу иметь возможность получать ( Открывать записи «ИЛИ» записи с Перелив )

Важно PS: у меня не может быть двух хранимых процедур (1 для ИЛИ и 1 для И), поскольку мои процедуры не такие короткие, как в примере выше, потому что как только я что-то изменю в одной процедуре, мне придется делать точные те же изменения во втором, и это не очень хорошее кодирование.

Важно PS2: я не хочу портить структуру хранимой процедуры. Я хочу использовать свою хранимую процедуру как «И» или «ИЛИ» всякий раз, когда я хочу (возможно, используя другой параметр), и способ, которым я пытался сделать это, использовал динамический sql, как в ссылке ниже

SQL Server, можно ли использовать оператор T-SQL как переменную? Или что-то в этом роде

но мне не удалось решить это.

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

Редактировать: Здесь я приведу пример, чтобы более четко показать проблему

Ниже кода, в списке флажков ничего не выбрано, возвращается 42703 (Запомните это число) строк

declare @op varchar(3)
set @op = 'AND'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''No''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''No''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

Ниже выделен код ASIM, возвращается 9349 строки

declare @op varchar(3)
set @op = 'AND'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''No''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

Я больше не буду давать тот же код, потому что логика одна и та же, «Нет» превращается в «Да», когда выбран флажок, и это структура кода.

ASIM и SonGrup выбранные возвращает 5885 строк ASIM и SonGrup и DortUzeri выбранные возвращает 1385 строки

Приведенный выше код прекрасно работает с AND, поэтому, когда я хотел использовать оператор OR, я должен получить результат 37696 , который является результатом приведенного ниже кода

SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
ASIM LIKE '%S%' OR SonGrup LIKE 'Son Grup' OR DortUzeri LIKE 'Dört ve Üzeri'

Итак, я выполнил код с оператором ИЛИ, в котором выбраны три компонента списка флажков, код приведен ниже и возвращает 37696 , что правильно.

declare @op varchar(3)
set @op = 'OR'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''Yes''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''Yes''=''No'') '
exec(@query)

Проблема возникает, когда один из компонентов контрольного списка не проверен, вот для 3-го компонента не проверена версия кода,

declare @op varchar(3)
set @op = 'OR'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''Yes''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

Приведенный выше код должен был вернуть 34613 , который я нашел с помощью следующего

SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
ASIM LIKE '%S%' OR SonGrup LIKE 'Son Grup'

Однако возвращается 42703 (число, которое я хотел, чтобы вы запомнили, вызвано из-за '' Нет '' = '' Нет ''), вот где возникает моя проблема. Здесь я не смог найти решение.

1 Ответ

2 голосов
/ 08 июля 2010

Вы должны использовать динамический sql - так как синтаксис проще для глаз, это также даст вашему запросу больше шансов выполнить.

Если вы можете, то я, вероятно, построю динамический sql вваше приложение, а не в хранимой процедуре, однако, если вам действительно нужно вызвать хранимую процедуру, то это также работает:

Отказ от ответственности: Обычно я никогда не пишу динамический SQL внутри хранимой процедуры, иУ меня также не установлен SQL-сервер на этом компьютере, чтобы убедиться, что работает следующее, однако, надеюсь, это поможет:

declare @op varchar(3)

IF @operator = "AND"
    set @op = "AND"
ELSE
    set @op = "OR"

declare @query varchar(max)
set @query = "select * from myRecordsTable WHERE" +

IF @param1 <> "No"
    set @query = @query + " Overflow LIKE '%O%' " + @op
IF @param2 <> ' No'
    set @query = " OpenClose = 'Open' " + @op

IF @operator = "AND"
    set @query = @query + " 1=1"
IF @operator = "OR"
    set @query = @query + " 1=0"

exec(@query)

Важные примечания:

  • Я проверяю значение @operator явным образом, чтобы избежать внедрения SQL (никогда не доверяю своему вызывающему)будет первым или последним.Оптимизатор SQL-сервера оптимизирует это как тавтологию в начале процесса оптимизации.
...