現在、私のクエリのWHERE句で次のSQL文を使用するJavaで準備された文がありますが、これを制限する関数に書き直したいと思いますユーザパラメータはそれに渡され、おそらくより効率的になります。ヌル検索を含むwhere句の関数を使用する
(
(USER_PARAM2 IS NULL AND
(COLUMN_NAME = nvl(USER_PARAM1, COLUMN_NAME) OR
(nvl(USER_PARAM1, COLUMN_NAME) IS NULL)
)
)
OR
(USER_PARAM2 IS NOT NULL AND COLUMN_NAME IS NULL)
)
USER_PARAM1とUSER_PARAM2は、ユーザーが準備したステートメントに渡されます。 USER_PARAM1は、この特定のCOLUMN_NAMEを検索するアプリケーションのユーザーを表します。ユーザーがこのパラメーターを含まない場合は、デフォルトでNULLになります。 USER_PARAM2は、ユーザーがこのCOLUMN_NAMEでNULL値のみの検索をリクエストできるようにするための方法でした。また、ユーザーによって渡された場合はUSER_PARAM2を 'true'に設定し、ユーザーが指定しなかった場合はNULLを設定するサーバーロジックもあります。
USER_PARAM2が宣言されている場合は、NULLのCOLUMN_NAME値のみが返されることになります。 USER_PARAM2が宣言されておらず、USER_PARAM1が宣言された場合は、COLUMN_NAME = USER_PARAM1のみが返されます。いずれのユーザー・パラメーターも宣言されていない場合、すべての行が戻されます。
誰でも私にこれを助けることができますか?事前に おかげで...
EDIT: ただ明確にするこれが私の現在のクエリが(..他のWHERE句の文なし)
SELECT *
FROM TABLE_NAME
WHERE (
(USER_PARAM2 IS NULL AND
(COLUMN_NAME = nvl(USER_PARAM1, COLUMN_NAME) OR
(nvl(USER_PARAM1, COLUMN_NAME) IS NULL)
)
)
OR
(USER_PARAM2 IS NOT NULL AND COLUMN_NAME IS NULL)
)
に見える...これはどこ私が希望です方法です...に取得したいEDIT#2
SELECT *
FROM TABLE_NAME
WHERE customSearchFunction(USER_PARAM1, USER_PARAM2, COLUMN_NAME)
: OKは、その別の同僚が、これで私を助けて...
CREATE OR REPLACE function searchNumber (pVal IN NUMBER, onlySearchForNull IN CHAR, column_value IN NUMBER)
RETURN NUMBER
IS
BEGIN
IF onlySearchForNull IS NULL THEN
IF pVal IS NULL THEN
RETURN 1;
ELSE
IF pVal = column_value THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END IF;
ELSE
IF column_value IS NULL THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END IF;
END;
...これは私の最初の試験で..
SELECT *
FROM TABLE_NAME
WHERE 1=searchNumber(USER_PARAM1, USER_PARAM2, COLUMN_NAME);
を動作するようです...それで私が持っている唯一の問題は、私が始めた、複雑なSQL文の対 1)のパフォーマンス上の問題だろう。 2)各データタイプに同様の関数を作成する必要があります。 しかし、後者は私にはあまり問題ではありません。
EDIT#3 2012年2月1日
だから我々は、コード/クエリ清浄度がパフォーマンスを切り札機能ベースのアプローチを使用している間、私は、以下の選んだ解決策と一緒に行くことになりました。関数ベースのアプローチでは、純粋なSQLを使用するよりも悪化していることがわかりました。
皆さん、ありがとうございました。
EDIT#4 2012年2月14日
は、だから私は、@のdanihpのソリューションの明快さと@に仮想テーブルの概念を適用するアランのソリューションは、明快さとパフォーマンスの面で非常に素晴らしい全体的なソリューションを提供していることに気づい振り返ります。ここに私が今持っているものがあります
WITH params AS (SELECT user_param1 AS param, user_param2 AS param_nullsOnly FROM DUAL)
SELECT *
FROM table_name, params p
WHERE (nvl(p.param_nullsOnly, p.param) IS NULL --1)
OR p.param_nullsOnly IS NOT NULL AND column_name IS NULL --2)
OR p.param IS NOT NULL AND column_name = p.param --3)
)
-- 1) Test if all rows should be returned
-- 2) Test if only NULL values should be returned
-- 3) Test if param equals the column value
おかげさまで、提案とコメントをお寄せいただきありがとうございます。
なぜ機能を変更するのですか?ネイティブSQLは、見た目が乱雑ですが、確かに優れたパフォーマンスを発揮します。 –
実際に関数が必要な場合は、 "customSearchFunction"がvarchar2値(たとえばS/N)を返す必要があります。 customSearchFunction(USER_PARAM1、USER_PARAM2、COLUMN_NAME)= 'S' –
関数を使用すると、文を評価するときにテーブル全体を強制的にスキャンする可能性があります。小さなテーブル(または小さなテーブルのジョイン)の場合、これは問題ではないかもしれませんが、大きなテーブルの場合は、パフォーマンスが大幅に向上する可能性があります。 YMMV。 –