7

ここで、WHERE句内でCASE式を使用することについて読みました:

http://scottelkin.com/sql/using-a-case-statement-in-a-sql-where-clause/

これを使用して、ユーザーのアプリケーションによって渡される契約番号に基づいて、select ステートメントから結果をフィルター処理しようとしています。私のコードは現在、渡されたものに関係なく「無効なパラメーター」のエラーをスローします。CASE 式のない WHERE 句のように、SELECT/FROM が正常に機能していることを確認しました。これが私のコードです。

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)

コードの冗長性はトラブルシューティングの目的であり、後で CASE でワイルドカード フィルタリングを使用する予定です。私は今、構文を理解することに集中しています。これにより、パラメーターがテーブルに格納されている契約番号と一致するすべてのレコードが返されるはずです。ヘルプやアドバイスをいただければ幸いです。

4

12 に答える 12

9

これを実行してもよろしいですか?あなたのcaseステートメントは常にを返します@ContractNo。私はあなたが探しているのはこれだと思います:

where 
    case @ContractNo 
        when 0 then tblContracts.ContractNo 
        else @ContractNo 
    end = tblContracts.ContractNo

上記のフィルターは、「ContractNoパラメーターと等しい場合はコントラクトを、パラメーターが0の場合はすべてのコントラクトを指定してください。

前のフィルターは、契約番号フィールドがパラメーターと完全に等しい場合にのみフィルター処理されました。

とにかく、代わりにこれを行う必要があります。

where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo

ロジックははるかに理解しやすく、それに加えて(これについては引用しないでください)、オプティマイザーはおそらくcaseステートメントの外でより適切に機能します。

于 2009-01-05T20:47:18.630 に答える
7

あなたの説明を読んだ後、これなしでこれを行うより良い方法がありますCASE:

WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo

これは、一致する契約番号のみを返します。ただし@ContractNo、0 の場合はすべてのレコードを返します。

編集: casperOne が同じことを提案していることに気付きました。私はそれを見ませんでした。自分を大きくしてください。

于 2009-01-05T21:15:27.713 に答える
2

たぶんあなたは@ContractNoを宣言するのを忘れましたか?0およびtblContracts.ContractNoに匹敵しますか?

于 2009-01-05T20:48:18.907 に答える
2

とにかく間違った場所にある括弧を除外してみてください - 正しいものは "END" の後にあるはずです。

于 2009-01-05T20:44:22.003 に答える
1

次のように、右括弧を = の前に移動します。

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END)=tblContracts.ContractNo

ただし、このケースステートメントが何をするのかわかりません... @ContractNo = 0 の場合、またはそうでない場合は同じものを返します...

正しい構文は次のとおりです。

  Select...
  ...
  Where(
    Case
      When <Condition>
        Then <Return if true>
        Else <Return if false>
      End
 ) = <Whatever is being matched to the output of the case statement>

ただし、構文に関係なく、この例はあまり意味がありません。一致する、または契約番号が 0 のすべてのアイテムを探している場合は、次のようにします。

Select...
...
Where (
  @ContractNo = 0 Or
  @ContractNo = tblContracts.ContractNo
)

これは、case ステートメントを使用しようとしているものよりもはるかに理にかなっているようです。

編集:私は質問を少し読み違えたに違いありません.paramが欠落しているということは、通常、パラメーター(この場合は@ContractNo)がクエリ/手順の範囲で宣言されていないことを意味します。しかし、誰かがすでにそれを指摘しているので、私はそれを信用することはできません.

于 2009-01-05T20:44:58.587 に答える
1

Recursive の投稿は、私の問題を正確に解決しました。

元の投稿の明快さについての苦情を見ました。今後、自分の言っていることをよりストレートに伝えるにはどうすればよいでしょうか? 私はコードに関する質問の言い回しに慣れていません。2 番目の投稿のように、拡張された詳細を提供する必要がありましたか?

すべての助けをありがとう。

于 2009-01-05T21:22:28.120 に答える
1

「0の場合はパラメーターを指定し、それ以外の場合はパラメーターのみを指定する」全体を含むcaseステートメントの理由は、構文を正しくするためにテストするためでした。もともと、私は「0 の場合は '%' を渡して、すべての値を返す」と言ってみました。そこに投稿したコードは、'Invalid Parameter' を取得し続け、構文に何か問題があるに違いないと考えたためでした。というように基本的なパラメータ合わせに分けましたが、

WHERE @ContractNo = tblContracts.ContractNo

正常にレコードを返しました。もう少し説明しましょう。

私はさまざまなテーブルの束からプルし、select ステートメントに含まれていない情報でコンテンツをフィルタリングしています (つまり、tblContracts は Select によって情報がプルされておらず、Where でのみ使用されます)。ユーザーは、さまざまな契約番号とデフォルト値の「すべて」を持つコンボ ボックスから選択します。

コンボ ボックスのインデックスが変更されたときのイベントを作成します。「すべて」の場合、パラメーターとして 0 が渡されるので、フィルター処理を行いません。それ以外の場合は、その契約番号 (Else @ContractNo の理由) の情報が必要です。

于 2009-01-05T21:05:58.700 に答える
0

こんな意味じゃないの?

SELECT * 
    FROM tblContracts
    WHERE     
    CASE 
       WHEN tblContracts.ContractNo = 0 THEN @ContractNo 
       ELSE tblContracts.ContractNo
    END = tblContracts.ContractNo

ここで、@ ContractNoは、tblContracts.ContractNoと同じデータ型の変数です。

于 2009-01-05T20:46:17.990 に答える
0

なぜcaseステートメントが必要なのですか?

WHen @ContractNo = 0 then(0 = tblContracts.ContractNo)else @ContractNo then(@ContractNo = tblContracts.ContractNo)

これは単純に次のように書くことができるので、これは意味がありません

ここで@contractNo=tblContracts.contractNo

于 2009-01-05T20:47:28.050 に答える
0

契約番号は実際には数値ですか、それとも常にたまたま数値である文字列ですか。テーブルとパラメーター、および CASE ステートメントの間のデータ型を確認してください (たとえば、「= 0」または「= '0'」)。

于 2009-01-05T21:00:51.987 に答える
0

この構文は機能するはずです (Oracle では機能します)。

WHERE CASE WHEN tblContracts.ContractNo = 0 
           THEN @ContractNo 
           ELSE tblContracts.ContractNo
      END = tblContracts.ContractNo
于 2009-01-05T21:23:24.327 に答える
0

あなたが言う時:

私はさまざまなテーブルの束からプルし、select ステートメントに含まれていない情報でコンテンツをフィルタリングしています (つまり、tblContracts は Select によって情報がプルされておらず、Where でのみ使用されます)。ユーザーは、さまざまな契約番号とデフォルト値の「すべて」を持つコンボ ボックスから選択します。

次に、「存在する場所」句が必要だと私には思えます。そのテーブルから情報を引き出していないので?!

于 2009-01-05T21:38:26.840 に答える