sql >> データベース >  >> RDS >> Oracle

Oracle でプロシージャの結果を外部に表示する方法

    あなたが示した手順をテストするには、次のようにします:

    declare
      l_id hr_position.id%type;
      l_group_name hr_position.group_name%type;
      l_group_level hr_position.group_level%type;
    begin
      drill_record_position('D', l_id, l_group_name, l_group_level);
      dbms_output.put_line(l_id ||':'|| l_group_name ||':'|| l_group_level);
    end;
    /
      

    しかし、それ、またはより具体的には、プロシージャは、渡された値の型のクエリの結果セットに 1 つの行がある場合にのみ機能します。複数の行が返されることを期待しているようですが (行が多すぎます)、そうでない場合もあります (データが見つかりません)。

    したがって、あなたの質問は、あなたが試した検索/テスト方法のいずれかで動作するように、手順をどのように作成するかに関するものであるように思われます.

    プロシージャが複数の行を返す必要がある場合は、ref カーソルを使用できます。例:

    create or replace procedure drill_record_position (
      p_record_type in varchar2,
      p_ref_cursor out sys_refcursor
    )
    as
    begin
      open p_ref_cursor for
        select hr.id, hr.group_name, hr.group_level
        from hr_position hr
        join drill_position dp
        on hr.id = dp.id
        where dp.typevalue = p_record_type;
    end drill_record_position;
    /
      

    次のようなものでテストできます:

    declare
      l_ref_cursor sys_refcursor;
      l_id hr_position.id%type;
      l_group_name hr_position.group_name%type;
      l_group_level hr_position.group_level%type;
    begin
      drill_record_position('D', l_ref_cursor);
      loop
        fetch l_ref_cursor into l_id, l_group_name, l_group_level;
        exit when l_ref_cursor%notfound;
        dbms_output.put_line(l_id ||':'|| l_group_name ||':'|| l_group_level);
      end loop;
      close l_ref_cursor;
    end;
    /
      

    これは関数として行うこともできます。これは、アプリケーションから操作する方が簡単かもしれません:

    -- drop procedure drill_record_position;
    
    create or replace function drill_record_position (p_record_type in varchar2)
    return sys_refcursor as
      l_ref_cursor sys_refcursor;
    begin
      open l_ref_cursor for
        select hr.id, hr.group_name, hr.group_level
        from hr_position hr
        join drill_position dp
        on hr.id = dp.id
        where dp.typevalue = p_record_type;
      return l_ref_cursor;
    end drill_record_position;
    /
    
    declare
      l_ref_cursor sys_refcursor;
      l_id hr_position.id%type;
      l_group_name hr_position.group_name%type;
      l_group_level hr_position.group_level%type;
    begin
      l_ref_cursor := drill_record_position('D');
      loop
        fetch l_ref_cursor into l_id, l_group_name, l_group_level;
        exit when l_ref_cursor%notfound;
        dbms_output.put_line(l_id ||':'|| l_group_name ||':'|| l_group_level);
      end loop;
      close l_ref_cursor;
    end;
    /
      

    コレクションとパイプライン化された関数を使用してこれを行うこともできますが、これはセットアップに手間がかかります:

    create type t_drill_obj as object (
       -- use your real data types...
      id number,
      group_name varchar2(10),
      group_level number
    )
    /
    
    create type t_drill_tab as table of t_drill_obj
    /
    
    create or replace function drill_record_position (p_record_type in varchar2)
    return t_drill_tab pipelined as
    begin
      for l_row in (
        select t_drill_obj(hr.id, hr.group_name, hr.group_level) as obj
        from hr_position hr
        join drill_position dp
        on hr.id = dp.id
        where dp.typevalue = p_record_type
      )
      loop
        pipe row (l_row.obj);
      end loop;
      return;
    end drill_record_position;
    /
      

    ただし、別のクエリの一部として呼び出し、必要に応じて結果に結合することもできます:

    select * from table(drill_record_position('D'));
      


    1. MYSQLWorkbenchで構文エラーを宣言する

    2. すべてのテーブルから選択

    3. レシピデータベース、材料で検索

    4. OracleのINITCAP()関数