2010-10-28 4 views
2

У меня есть эта проблема, когда мне нужно установить «необязательные» параметры для моей хранимой процедуры, чтобы она работала нормально. Например, у меня есть это:Параметры sql, которые могут быть необязательными

CREATE PROCEDURE [dbo].[Search] 
(
@StartTime datetime = NULL, 
@EndTime datetime = NULL, 
@CustomerEmail nvarchar(255) = NULL, 
@OrderStatusID int 
) 

Сейчас, на мой веб-сайт .net У меня есть это как пример, пожалуйста, имейте в виду, что может быть только один параметр, или там может быть все из них:

commAdvanced.Parameters.Add("@StartTime", SqlDbType.DateTime).Value = startDate; 
commAdvanced.Parameters.Add("@EndTime", SqlDbType.DateTime).Value = endDate; 
commAdvanced.Parameters.Add("@CustomerEmail", SqlDbType.nvarchar).Value = null; 
commAdvanced.Parameters.Add("@OrderStatusID", SqlDbType.Int).Value = null; 

И это запрос:

SELECT * FROM Order 
WHERE CreatedOn > CAST(@StartTime as datetime) 
    AND CreatedOn < CAST(@EndTime as datetime) 
    AND Order.OrderStatusID = @OrderStatusID 
    AND Order.CustomerEmail = @PaymentStatusID 

Я не подвожу никаких записей, когда я делаю это, может кто-то пожалуйста, помогите мне, что мне нужно сделать, чтобы изменить.

+1

Откуда появился '@ PaymentStatusID' в вашем операторе' SELECT'? – Oded

ответ

0

Согласно вашему вопросу, из 4 параметров можно передать один или все параметры вашей процедуре. И ваш запрос имеет все столбцы, проверенные в разделе where. Поэтому, если я правильно понимаю, в настоящее время вы не получите никаких записей, пока все 4 параметра не будут переданы с действительными данными.

Попробуйте это, я просто создаю запрос, а затем выполняю его. Я проверяю каждый из параметров для нулей, и только значения параметра, которые не являются нулями, включены в предложение where.

declare @sqlstring varchar(1000) 

set @sqlstring = 'SELECT * FROM Order WHERE 1=1 ' 

if @StartTime <> null OR @StartTime <> '' 
BEGIN 
set @sqlstring = @sqlstring + 'AND CreatedOn > CAST(@StartTime as datetime) ' 
END 

if @EndTime <> null OR @EndTime <> '' 
BEGIN 
set @sqlstring = @sqlstring + 'AND CreatedOn < CAST(@EndTime as datetime) ' 
END 

if @OrderStatusID <> null OR @OrderStatusID <> '' 
BEGIN 
set @sqlstring = @sqlstring + 'AND OrderStatusID = @OrderStatusID ' 
END 

if @CustomerEmail <> null OR @CustomerEmail <> '' 
BEGIN 
set @sqlstring = @sqlstring + 'AND CustomerEmail > @CustomerEmail ' 
END 

print @sqlstring 
Exec(@sqlstring) 
0

Вам необходимо пройти в DBNull.Value для тех параметров вы хотите оставить NULL (не только .NET null):

commAdvanced.Parameters.Add("@CustomerEmail", SqlDbType.nvarchar).Value = DBNull.Value; 
commAdvanced.Parameters.Add("@OrderStatusID", SqlDbType.Int).Value = DBNull.Value; 

Это должно сделать трюк.

Также: если указан параметр типа varchar или nvarchar, я бы рекомендовал всегда указать его длину.

1

Предполагая, что есть опечатка в запросе на выборку, возможно, попробовать

AND Order.CustomerEmail = ISNULL(@CustomerEmail, CustomerEmail)
And OrderStatusID = ISNULL(@OrderStatusID, OrderStatusID)

Также вам не нужно бросить @StartTime т.д. DateTime. Они уже такого типа, нет?

0

Я думаю, что это похоже на ваш запрос, являющийся неправильным.

Давайте рассмотрим пример поставки только @StartTime. Ваш запрос будет вычисляться:

SELECT * FROM Order 
WHERE CreatedOn > CAST(@StartTime as datetime) 
    AND CreatedOn < null 
    AND Order.OrderStatusID = null 
    AND Order.CustomerEmail = null 

Предполагая ANSI NULLs включен, нет значения, которое по сравнению с нулевым возвращает истинный результат, следовательно, ваш пустой набора результатов.

Я думаю, что ответ Ноэля ближе - я хотел бы предложить:

SELECT * FROM Order 
WHERE (@StartTime is null or CreatedOn > @StartTime) 
    AND (@EndTime is null or CreatedOn < @EndTime) 
    AND Order.OrderStatusID = isnull(@OrderStatusID, Order.OrderStatusID) 
    AND Order.CustomerEmail = isnull(@CustomerEmail, Order.CustomerEmail) 

marc_s тоже правильно - если вы явно хотите установить значение @ параметра в SQL NULL, установить его в качестве

commAdvanced.Parameters.Add("@CustomerEmail", SqlDbType.nvarchar).Value = DBNull.Value;   
commAdvanced.Parameters.Add("@OrderStatusID", SqlDbType.Int).Value = DBNull.Value; 

Однако, поскольку вы предоставили значения по умолчанию null в вашем сохраненном процессе (кроме @OrderStatusID - опечатка?), вам фактически не нужно добавлять эти параметры в команду вообще.

0

Будьте осторожны: лучшее решение для ремонтопригодности может быть неэффективным для производительности и масштабируемости (и обратите внимание, что игровое поле изменилось со времен SQL Server 2008).

Это довольно большая тема, и я рекомендую вам прочитать Dynamic Search Conditions in T-SQL от Erland Sommarskog.

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