2

ストアド プロシージャが正常に動作するように「オプション」のパラメータを設定する必要があるという問題があります。たとえば、私はこれを持っています:

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

さて、私の .net Web サイトでは、例として次のようなものがあります。パラメータは 1 つしかない場合もあれば、すべてある場合もあることに注意してください。

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

それを行っているときにレコードが取得されません。何を変更する必要があるか教えてください。

4

5 に答える 5

1

選択クエリにタイプミスがあると仮定して、おそらく試してみてください

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

また、@StartTimeなどをdatetimeにキャストする必要はありません。彼らはすでにそのタイプですよね?

于 2010-10-28T19:04:15.940 に答える
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も正しいです-@パラメータ値を明示的にSQLnullに設定する場合は、次のように設定します

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

ただし、ストアドプロシージャにデフォルト値のnullを指定しているため(@ OrderStatusID --typo?を除く)、実際にこれらのパラメータをコマンドに追加する必要はありません。

于 2010-10-28T20:07:56.280 に答える
0

DBNull.ValueNULL のままにしたいパラメータを渡す必要があります( .NET だけではありませんnull):

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

これでうまくいくはずです。

また、 typevarcharまたはのパラメーターを指定する場合は、常にその長さを指定するnvarcharことをお勧めします。

于 2010-10-28T19:02:39.420 に答える
0

警告: 保守性のための最適なソリューションは、パフォーマンスとスケーラビリティには適していない可能性があります (また、SQL Server 2008 以降、競争の場が変わったことに注意してください)。

これは非常に大きなトピックであり、Erland Sommarskog によるDynamic Search Conditions in T-SQLを読むことをお勧めします。

于 2010-10-29T09:07:19.030 に答える
0

あなたの質問によると、4 つのパラメーターのうち、1 つまたはすべてのパラメーターをプロシージャーに渡すことができます。そして、クエリには、where 句でチェックされたすべての列があります。したがって、現在、4つのパラメーターすべてが有効なデータで渡されるまで、レコードを取得することはできません。

これを試してみてください。私は単純にクエリを作成して実行しています。各パラメーターの null をチェックし、null ではないパラメーター値のみを 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)
于 2010-10-28T19:54:03.930 に答える