1

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;
4

1 に答える 1

3

プレーン SQL から呼び出すことができるようにしたい場合、それ以外の場合は a を使用できBOOLEANますが、固定値を渡して代わりに解釈することができます。0/1、Y/N などが一般的です。1 を true (およびそれ以外は false) として使用する例:

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 

式を文字列として渡すことができる場合、たとえば、動的 SQL と一緒に何かをハックできると思います。

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('1=1', 42) from dual;

したがって、次のように条件を文字列に構築する必要があります。

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

これはかなり扱いにくいように見え、ほとんどすべてを条件として渡すことができますが、これはもちろん危険な場合があります (控えめに言っても、SQL インジェクションの可能性があります)。可能な限り特定の「条件」のみを使用する場合は、単純な引数を取り、ブール条件値を計算して実際の関数を呼び出す関数ラッパーを使用する方がよい場合があるため、次のようなものを呼び出しますmy_func_eq(42, a, b)

また、関数が本当に必要かどうかも検討します。もちろん、関数が何をしているかにもよりますが、case ステートメントなどの単純なクエリで同じ効果を達成できる可能性があります。

于 2012-04-11T11:13:15.947 に答える