2つのIN
パラメータを使用して関数を記述します。最初のパラメータはvarchar
で、2番目のパラメータはvarchars
のリストです。これらに基づいて、列の量とタイプvarchar
の名前が異なるテーブルを返します。
私が見た限りでは、常にオブジェクト/レコードとそのテーブルタイプを作成する必要があります。これは私のアイデアが機能しないことを意味しますか?基本的な目標は、システムコマンドの出力をテーブルとして呼び出し先に返すことです。
編集:タスクの詳細。 OSコマンドを発行し、出力を消費して、テーブルとして返したいのですが。 OSコマンドからの出力は、CSV形式のデータになります。実行時には、返される行の数はわかりませんが、2番目の引数として渡される列の数しかわかりません。私はJavaを動的STRUCT
とそれらを含むARRAY
で使用することを考えていました。前者のアプローチを好むでしょうが。
次のようになります。
create function(clob query, list of varchars cols) returns table
begin
execute system command(query, cols);
examine sysout from command;
return tabular data from syscmd as table;
end
かなり複雑ですが、 変数構造を返すパイプラインテーブル関数 を書くことは可能です。パイプラインテーブル関数は2つの引数を取り、Oracle Data CartridgeインターフェイスとAnyDataSetタイプの魔法を使用して、実行時に動的構造を返すことができます。その後、それをテーブルであるかのように、後続のSQLステートメントで使用できます。
SELECT *
FROM TABLE( your_pipelined_function( p_1, p_2 ));
同じサンプル実装について説明しているさらにいくつかのリファレンス
tmpビューを作成して、ビューを動的に置き換えることができます。
create or replace view tmp_view as select 1 x from dual;
/
create or replace package pkg_input_sql is
cursor my_cursor is select * from tmp_view;
my_rec_type my_cursor%rowtype;
type my_tab_type is table of my_cursor%rowtype;
function get_cursor(p_sqlstr varchar2) return sys_refcursor;
function get_table return my_tab_type
pipelined;
end pkg_input_sql;
/
create or replace package body pkg_input_sql is
function get_cursor(p_sqlstr varchar2) return sys_refcursor as
my_cursor sys_refcursor;
begin
open my_cursor for p_sqlstr;
return my_cursor;
end get_cursor;
function get_table return my_tab_type
pipelined is
my_tab my_tab_type;
i pls_integer;
my_cursor sys_refcursor;
begin
my_cursor := get_cursor('select * from tmp_view');
fetch my_cursor bulk collect
into my_tab;
for i in 1 .. my_tab.count loop
pipe row(my_tab(i));
end loop;
end;
begin
null;
end pkg_input_sql;
/
create or replace procedure create_tmp_view(p_sqlstr varchar2) is
begin
execute immediate 'create or replace view tmp_view as ' || p_sqlstr;
dbms_utility.exec_ddl_statement('alter package pkg_get_sql compile package');
dbms_session.reset_package; -- to avoid ora-04068
end create_tmp_view;
実行結果:
私はあなたの最善のアプローチは動的テーブルを送り返す試みを放棄することだと思います(私はあなたがmight一時テーブルを作成し、refcursorをそれに戻すことができると思いますが、ここではわかりません) 。
ここでの私の好ましいアプローチは、XML文書などのような、より柔軟な形式で結果を生成し、それを返すことです。これにより、関数のスキャン後に列を決定する必要がなく、必要な柔軟性が得られます。