2012-04-11 8 views
0

Oracleのユーザー定義関数に条件(真偽値)を渡す(何らかの方法で問題あり、ハックする)可能性があるのでしょうか。 - それ以外の場合はあなただけBOOLEANを使用することができます - あなたは固定値を渡して、代わりにそれを解釈することができますが、プレーンSQLから呼び出すことができるようにしたいと仮定すると、Oracleユーザー定義関数に条件を渡すことはできますか?

CREATE OR REPLACE FUNCTION SCHEMA.MY_FUNC (
    condition IN ???, 
    my_value IN NUMBER) RETURN NUMBER IS 
BEGIN 
    IF condition THEN 
     RETURN my_value + 1; 
    END IF; 
    RETURN my_value; 
END; 
+1

なぜ、「BOOLEAN」を使用しないのですか? –

+0

関数の外部で条件をテストし、1または0を関数に渡しますか? – MatBailie

+0

@PeterLang単純なSQLコンテキストではBOOLEANを使用できません。 –

答えて

3

はのは、私のような何かをしたいとしましょう。 0/1、Y/Nなどは共通です。あなたは、文字列として式を渡すことができる場合、たとえば、あなたは、動的SQLと一緒に何かをハック可能性が

CREATE OR REPLACE FUNCTION MY_FUNC (
    condition IN NUMBER, 
    my_value IN NUMBER) RETURN NUMBER IS 
BEGIN 
    IF condition = 1 THEN 
     RETURN my_value + 1; 
    END IF; 
    RETURN my_value; 
END; 
/

FUNCTION MY_FUNC compiled 

select my_func(0, 42) from dual; 
select my_func(1, 42) from dual; 

MY_FUNC(0,42) 
------------- 
      42 

MY_FUNC(1,42) 
------------- 
      43 

を 私が思う:例えば1として、真(偽として何か)を使用して

だから、あなたは同じように、文字列にあなたの条件アップを構築する必要があると思います

select my_func('1=1', 42) from dual; 

:あなたは次のように呼び出す必要があるだろう

CREATE OR REPLACE FUNCTION my_func (
    condition IN varchar2, 
    my_value IN NUMBER) RETURN NUMBER IS 
    boolstr VARCHAR2(5); 
BEGIN 
    EXECUTE IMMEDIATE 'SELECT CASE WHEN ' || condition 
     || ' THEN ''true'' ELSE ''false'' END FROM dual' INTO boolstr; 
    IF boolstr = 'true' THEN 
     RETURN my_value + 1; 
    END IF; 
    RETURN my_value; 
END; 
/

select my_func(a ||'='|| b, 42) from <some table with a and b columns>; 

これはかなり扱いにくいようで、ほとんど何ももちろん危険かもしれ条件として渡すことができます(SQLインジェクションの可能性を、穏やかにそれを置くために)。できるだけ特定の '条件'しかないのであれば、簡単な引数をとり、真の関数を呼び出すブール条件値を求める関数ラッパーを持つ方が良いかもしれないので、my_func_eq(42, a, b)のようなものを呼び出します。

私はまた、関数が本当に必要かどうかを検討したいと思います。もちろん、関数が何をしているかによって、簡単なクエリで同じ効果を得ることができます。ケースステートメント。

+0

'SELECT my_func(a = b)'や 'SELECT my_func(CASE WHEN a = b THEN 1 ELSE 0)'以外の条件を直接使用する機会はありませんか?申し訳ありませんが、私はOracleの新機能です... * PS:関数作成後の '/'記号は何ですか?私はそれもオラクルのドキュメントで見ることができますが、私はそれを得ることができません、私はテスト中に使用されていません... * –

+0

@ loernzo - 私は評価される文字列を渡すことが可能であることを示すバージョンを追加しました条件としては可能ですが、それは必ずしも良い考えではありません。 Peterが示唆しているように、あなたが本当にやろうとしていること、そしてなぜこの構造が必要だと思うのかを広げてください。 –

+0

また、少なくともSQL * PlusまたはSQL DeveloperからPL/SQLブロック(この場合は関数の作成)を実行するには、 '/'が必要です。あなたがスクリプトにそれを持っていれば、それはとにかく実行される最後のものですが、通常は混乱を避けるために常に使用する方がよいので、通常は必要です。 –

関連する問題