我有这个问题,我需要为我的存储过程设置“可选”参数才能正常工作。 例如,我有这个:
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
当我这样做时,我没有记录,有人可以帮助我,我需要改变什么。
答案 0 :(得分:1)
假设select查询中存在拼写错误,请尝试
AND Order.CustomerEmail = ISNULL(@CustomerEmail, CustomerEmail)
And OrderStatusID = ISNULL(@OrderStatusID, OrderStatusID)
此外,您无需将@StartTime等转换为datetime。他们已经属于那种类型,不是吗?
答案 1 :(得分: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
类型的参数,我建议始终指定其长度。
答案 2 :(得分: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)
答案 3 :(得分:0)
我认为这很简单,因为你的查询不正确。
让我们举一个仅提供@StartTime的例子。您的查询将评估为:
SELECT * FROM Order
WHERE CreatedOn > CAST(@StartTime as datetime)
AND CreatedOn < null
AND Order.OrderStatusID = null
AND Order.CustomerEmail = null
假设ANSI NULL为ON,则没有值与null相比返回真实结果,因此是空结果集。
我认为诺埃尔的回答最接近 - 我建议:
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;
但是,因为您在存储的proc 中提供了默认值null(除了@OrderStatusID - 错误?),所以实际上并不需要将这些参数添加到命令中。< / p>
答案 4 :(得分:0)
警告:可维护性的最佳解决方案可能不利于性能和可伸缩性(并注意自SQL Server 2008以来游戏领域已发生变化)。
这是一个非常大的话题,我建议你阅读Erland Sommarskog的Dynamic Search Conditions in T-SQL。