0

Javaでinstanceofを持っているように、pl_sql関数で入力パラメータのデータ型を決定する方法はありますか? ダンプ機能を使用してみましたが、クエリでのみ使用できます。

4

1 に答える 1

0

whereコメントから、入力パラメーターをループして動的クエリ文字列を作成し、おそらく手動で入力することなく句を作成したいようです。それは、メンテナンスと理解を難しくし、あまりメリットがないように思われます。

ただし、演​​習として、ビューからパラメーター定義をループできuser_argumentsます。問題は、名前を付けないと実際のパラメーター値を取得できないことです。その場合、値を直接動的文字列に入れる場合にのみデータ型が問題になります (これは実際にはループでは実行できません)。バインド変数としてではなく、とにかく行うのは悪いことです。また、バインド変数を使用している場合は、データ型を知る必要はありません。

したがって、主に私自身の娯楽のために、さまざまなデータ型のテーブルがある場合:

create table t42(col1 varchar2(10), col2 number, col3 date);
insert into t42 values ('data', 42, trunc(sysdate));

...そして、パラメーター名がテーブルの列名と一致する関数を使用すると、バインド変数を使用して動的文字列を作成できます。

create function f42(col1 t42.col1%type, col2 t42.col2%type,
    col3 t42.col3%type)
return varchar2 is
    str varchar(4000);
    result t42.col1%type;
    have_where boolean := false;
begin
    str := 'select col1 from t42';
    for r in (
        select argument_name, data_type
        from user_arguments
        where object_name = 'F42'
        and position > 0 -- to account for return type
        order by position
    ) loop
        if not have_where then
            have_where := true;
            str := str || ' where ';
        else
            str := str || ' and ';
        end if;
        str := str || r.argument_name || ' = :' || r.argument_name;
    end loop;

    dbms_output.put_line(str);

    execute immediate str into result using col1, col2, col3;
    return result;
end;
/

次に、SQL*Plus から呼び出すことができます。

SQL> var rc varchar2(10);
SQL> exec :rc := f42('data', 42, trunc(sysdate));

select col1 from t42 where COL1 = :COL1 and COL2 = :COL2 and COL3 = :COL3

PL/SQL procedure successfully completed.

SQL> print rc

RC
--------------------------------
data

明らかに非常に不自然な例ですが、usingすべてのパラメーターをリストする必要があるのは節だけで、より多くのパラメーターに対応できます。おもう。これは、これが良いアイデアだと思うという意味ではありません- ただの楽しみのために...

r.data_type必要に応じて、値を確認することで、データ型に基づいてループ内で操作を行うことができます。

        str := str || r.argument_name || ' = ';
        if r.data_type = 'DATE' then
            str := str || 'trunc(:' || r.argument_name || ')';
        else
            str := str || ':' || r.argument_name;
        end if;

...呼び出しで値を指定せずに呼び出すことができtruncます:

SQL> exec :rc := f42('data', 42, sysdate);

select col1 from t42 where COL1 = :COL1 and COL2 = :COL2 and COL3 = trunc(:COL3)

PL/SQL procedure successfully completed.

SQL> print rc

RC
--------------------------------
data

...しかし、それ以外は、動的文字列の各列の型を知る必要はありません。とにかくバインディングがそれを処理するからです。

于 2013-04-10T11:42:56.220 に答える