2016-04-25 7 views
3

У меня есть хранимая процедура, чтобы получить подробную информацию о счетах-фактурахпараметризованная ИНЕКЕ в SQL Server хранимой процедуры

некоторых случаях я получаю список счетов-фактур, посылая только InvoiceID Но в некоторых других случаях, мне нужно, чтобы получить список счетов-фактур в соответствии с полями поиска, предоставленными пользователем. Для этого я отправляю все поля в хранимую процедуру и использую эти параметры, как показано ниже. Я включил только 2 столбца, но их больше.

SELECT * FROM INVOICES I 
    WHERE 
    (@InvoiceNumber is null or I.InvoiceNumber = @InvoiceNumber) 
    and 
    (@PONo is null or I.PONo = @PONo) 

Есть ли способ отправить условие для предложения WHERE в качестве одного параметра?

+0

решение является динамическим sql, но лучше всего сузить реальные требуемые поля поиска (ответ «все поля обязательны» - это период времени.) И добавить их в качестве параметров. – Paolo

ответ

2

Да, это возможно с помощью Dynamic SQL, но я очень не рекомендую это делать.

SELECT * FROM tbl WHERE @condition:

Если вы планируете написать процедуру,

CREATE PROCEDURE search_sp @condition varchar(8000) AS 
    SELECT * FROM tbl WHERE @condition 

Просто забыть. Если вы делаете это, вы не завершили переход на использование хранимой процедуры, и вы все еще собираете свой код SQL-кода на клиенте.

Он также откроет ваше приложение для атак SQL-инъекций.

0

Если вы используете SQL Server 2016 или аналогичный (проверьте по телефону select compatibility_level, name from sys.databases и, видя, что ваш DB 130 или выше) то вы можете использовать встроенную функцию string_split.

Я нашел, что это работает лучше всего, как это (распространено для ясности)

CREATE PROCEDURE [dbo].[GetInvoices] 
    @InvoiceNumber int = NULL 
    @PONo nvarchar(1024) = NULL 
AS 
SELECT * from [Invoices] AS [i] 
WHERE 
    i.InvoiceNumber = ISNULL(@InvoiceNunber, i.InvoiceNunber) 
    AND CASE 
     WHEN @PONo is null 
     THEN 1 
     ELSE (CASE 
      WHEN i.PONo IN (select value from string_split(@PONo, ',')) 
      THEN 1 
      ELSE 0 
      END) 
     END 
     = 1 

Так что, если вы передаете в нуле на любой из этих параметров он получает переводятся как where x = x, которая всегда верно, и если вы проходите в CSV, он выбирает его из разделенной таблицы значений, которая, если присутствует, приводит к тому, что в предложении where равен where 1=1, что равно true или 0=1, если это значение отсутствует в списке ввода.

Таким образом, здесь вы можете указать номер счета, номер заказа или оба, либо ни один из них, и он должен вернуть то, что вы ожидаете.

Смежные вопросы