質問
ここでWHERE句内でCASE式を使用することについて読みました:
http:// scottelkin。 com / sql / using-a-case-statement-in-a-sql-where-clause /
これを使用して、ユーザーのアプリケーションから渡される契約番号に基づいて、selectステートメントからの結果をフィルター処理しようとしています。私のコードは現在、何が渡されても「Invalid parameter」というエラーをスローします。CASE式のないWHERE句のように、SELECT / FROMが正常に機能していることを確認しました。これが私のコードです。
WHERE (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)
コードの冗長性はトラブルシューティングを目的としています。CASEでワイルドカードフィルタリングを使用する予定です。私は今構文をダウンさせることに集中しています。これにより、テーブルに保存されている契約番号とパラメーターが一致するすべてのレコードが返されるはずです。ヘルプやアドバイスをいただければ幸いです。
解決
説明を読んだ後、 CASE
なしでこれを行うより良い方法があります:
WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo
これは、 @ContractNo
が0でない限り、一致する契約番号のみを返します。その場合、すべてのレコードを返します。
編集: casperOneは同じことを提案しました。私はそれを見ませんでした。自分を大きくしてください。
他のヒント
これを実行してもよろしいですか?ケースステートメントは常に @ContractNo
を返します。あなたが探しているのはこれだと思います:
where
case @ContractNo
when 0 then tblContracts.ContractNo
else @ContractNo
end = tblContracts.ContractNo
上記のフィルターは、「 ContractNo
がパラメーターに等しいコントラクト、またはパラメーターが0の場合はすべてのコントラクトを教えてください」と述べています。
前のフィルターは、契約番号フィールドがパラメーターと正確に等しい場合にのみフィルターされました。
とにかく、代わりにこれを行うべきです:
where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo
ロジックははるかに理解しやすく、その上(これについては引用しないでください)、おそらくオプティマイザーはcaseステートメントの外でより良く機能します。
とにかく間違った場所にある括弧を省いてみてください-正しい括弧は" END"の後でなければなりません。
@ContractNoを宣言するのを忘れたのでしょうか? 0とtblContracts.ContractNoに匹敵しますか?
再帰の投稿は私の問題を正確に解決しました。
元の投稿の明快さに不満がありました。将来、私が言っていることをより簡単にするために私は何ができますか?私は、コードに関する質問の言い回しに慣れておらず、コードの混乱をおforびします。 2番目の投稿のように、詳細を追加する必要がありましたか?
すべてのヘルプに感謝します。
閉じ括弧を=の前に移動します:
WHERE (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END)=tblContracts.ContractNo
このcaseステートメントが何をするのかわかりません... @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ステートメントを使用しようとしているものよりもはるかに理にかなっているようです。
編集:質問を少し間違えたに違いありません。通常、パラメーターが欠落しているということは、パラメーター(この場合@ContractNo)がクエリ/プロシージャのスコープで宣言されていないことを意味します。しかし、誰かがすでにそれを指摘していたので、私はそれを信用することはできません。
&quot; 0の場合はパラメーターを指定し、それ以外の場合はパラメーターのみを指定する&quot;を含むcaseステートメントの理由構文を正しくしようとテストしました。もともと、&quot; 0の場合は、すべての値を返すために '%'を渡すように言っていました。私がそこに投稿したコードは、「無効なパラメーター」を取得し続け、構文に何か問題があるに違いないと考えたためです。そのように一致する基本的なパラメーターに分けたとき、
WHERE @ContractNo = tblContracts.ContractNo
レコードを正常に返しました。もう少し説明しましょう。
さまざまなテーブルからプルし、selectステートメントに含まれていない情報でコンテンツをフィルタリングしています(つまり、tblContractsにはSelectによってプルされた情報がなく、Whereでのみ使用されています)。ユーザーは、異なる契約番号とデフォルト値の「すべて」を持つコンボボックスから選択します。
コンボボックスのインデックスが変更されたときのイベントを作成します。 「すべて」の場合、0がパラメーターとして渡されるため、フィルタリングは行われません。それ以外の場合は、その契約番号の情報が必要です(Else @ContractNoの理由)。
このようなことを意味していませんか?
SELECT *
FROM tblContracts
WHERE
CASE
WHEN tblContracts.ContractNo = 0 THEN @ContractNo
ELSE tblContracts.ContractNo
END = tblContracts.ContractNo
@ContractNoは、tblContracts.ContractNoと同じデータ型の変数です
なぜcaseステートメントが必要なのですか?
WHen @ContractNo = 0 then(0 = tblContracts.ContractNo) else @ContractNo then(@ContractNo = tblContracts.ContractNo)
これは単純に
と書くことができるので意味がありません@contractNo = tblContracts.contractNoの場所
契約番号は、実際は数値であるか、または常に数値である文字列です。テーブルとパラメーターおよびCASEステートメントの間のデータ型を確認します(たとえば、「quote = 0」または「quote = '0'&quot;」)
この構文は機能するはずです(Oracleで機能します)
WHERE CASE WHEN tblContracts.ContractNo = 0
THEN @ContractNo
ELSE tblContracts.ContractNo
END = tblContracts.ContractNo
言うとき:
さまざまなテーブルからプルし、selectステートメントに含まれていない情報でコンテンツをフィルタリングしています(つまり、tblContractsにはSelectによってプルされた情報がなく、Whereでのみ使用されています)。ユーザーは、異なる契約番号とデフォルト値の「すべて」を持つコンボボックスから選択します。
それから、「どこにあるか」が必要だと思います。句。あなたはそのテーブルから情報を引き出していないのですか?