0
create type data_type_1 as object (x number, y number)
/

create type table_type_1 as table of data_type_1
/

create or replace package xyz AS
      function main_xyz return table_type_1 pipelined;
      function sub_func return table_type_1 pipelined;
      function sub_func1 return table_type_1 pipelined;
end xyz;
/

create package body XYZ AS
    function main_xyz return data_type_1 pipelined is
        begin 
        --code
        --pipe row(sub_func); --edit_1
        FOR rec in (select * from table(sub_func1(x,y))) LOOP
               pipe row(rec);
        END LOOP;
        end;
    --function sub_func return data_type_1 pipelined is --edit_1
        --begin --edit_1
        --code --edit_1
        --pipe row(def); --def is data_type_1 --edit_1
        --end; --edit_1
     function sub_func_1(x in number, y in number) return data_type_1 pipelined is
        begin 
        --code
        loop
        pipe row(abc); --abc is data_type_1
        end loop;
        end;
 end;
 create package body ABC AS
     function main_ABC is
        begin 
        --code
        FOR rec in (select * from table(main_xyz)) LOOP
               pipe row(rec);
        END LOOP;
        end;
 end;

私が得るエラーは...

sub_func1 が呼び出される main_xyz のブロックでエラーが表示されます。

[エラー] PLS-00382 (): PLS-00382: 式の型が間違っています
[エラー] PLS-00306 (): PLS-00306: 呼び出しの引数の数または型が間違っています
[エラー] ORA-00904 (): PL /SQL: ORA-00904: : 無効な識別子
[エラー] PLS-00364 (): PLS-00364: ループ インデックス変数 'REC' の使用が無効です

上記のコードで何が間違っていますか? なぜ?

4

1 に答える 1

2

関数は を返しdata_type_1、テーブル コレクションもそれを消費しようとしています。ただし、単一の値のみを返すと予想される場合でも、両方ともコレクション型が必要です (この場合、ポイント パイプラインはあまりありません)。コレクション型を直接パイプすることはできません。コレクションのメンバーをパイプします。したがってdata_type_1、スカラーまたはオブジェクト/レコード型である必要があり、それらのコレクションである別の型が必要です。

create type data_type_1 as object (x number, y number)
/

create type table_type_1 as table of data_type_1
/

create or replace package xyz AS
  function main_xyz return table_type_1 pipelined;
  function sub_func return table_type_1 pipelined;
  function sub_func1 return table_type_1 pipelined;
end xyz;
/

create or replace package body xyz as
  function main_xyz return table_type_1 pipelined is
  begin 
    --code
    for rec in (select * from table(sub_func)) loop
      pipe row(data_type_1(rec.x, rec.y));
    end loop;
    for rec in (select * from table(sub_func1)) loop
      pipe row(data_type_1(rec.x, rec.y));
    end loop;
  end;

  function sub_func return table_type_1 pipelined is
    def data_type_1;
  begin 
    --code
    pipe row(def); --def is data_type_1
  end sub_func;

  function sub_func1 return table_type_1 pipelined is
    abc data_type_1;
  begin 
    --code
    loop
      pipe row (abc); --abc is data_type_1
    end loop;
  end sub_func1;
end xyz;
/

そこで、既存の のテーブル タイプを追加し、data_type_1代わりにそのテーブル タイプを返すように関数定義を変更しました。pipe rowまだ使用data_type_1- それぞれがテーブル タイプの行です。ループには、への直接呼び出しではなく、カーソルのクエリが必要なtable()ので、それも変更しました。またpipe row(sub_func);、クエリに対する同様のループも必要です。

これを PL/SQL としてのみタグ付けしましたがmain_xyz、プレーン SQL から呼び出すことを意図している可能性があり、それらのループで SQL コンテキストからサブ関数を呼び出しておりdata_type_1table_type_1PL/ ではなくスキーマ レベルで作成する必要があるためです。 SQL。(これは12c で少し変更されましたが、ここで役立つほどではありません)。

パッケージ仕様で宣言されたPL/SQL型としてそれらを持ちたい場合、PL/SQL以外のコンテキストから関数を呼び出すことはできず、ループを関数の呼び出しに置き換える必要がありますその後、返されたコレクションに対する反復が続きます。

于 2016-01-20T10:36:54.970 に答える