他の回答で述べられているように、関数がコンパイルされない理由は3つあります。
- 変数を宣言し、
v_names
それをとして参照していv_name
ます。
- PL / SQLの代入演算子は
:=
、等式演算子を使用しています=
。
- returnステートメントにセミコロンがありません。そのはず
return v_name;
関数のコンパイルは停止しませんが、変数v_names
はとして宣言されますvarchar2(10)
。複数の部下を持つマネージャーがすべての姓をこれに当てはめる可能性はほとんどありません。おそらく、この変数を最大サイズで宣言する必要があります。念のため。
あなたがこれを非常に非効率的な方法で行っていることを付け加えたいと思います。PL / SQLループではなく、SQLで文字列の集計を行う場合は、より適切です。11gリリース2から、listagg()
機能があります。それ以前のバージョンを使用している場合は、同じ結果を達成するための他の文字列集計手法がたくさんあります。
create or replace function employee ( p_manid in employees.manager_id%type
) return varchar2 is
v_names varchar2(32767); -- Maximum size, just in case
begin
select listagg(lastname, ', ') within group ( order by lastname )
into v_names
from employees
where manager_id = p_manid;
return v_names;
exception when no_data_found then
return null;
end;
/
私が行った他のいくつかの変更に注意してください:
- 関数パラメーターに変数とは異なる文字を付加して、どちらがどちらであるかを明確にします。
- その特定のマネージャーのデータがないことに対処するために、いくつかの例外処理を追加します。
,
私がNULLを返すデータがなかったら、あなたは戻ったでしょう。代わりにコンマを返したい場合は、これを例外の中に入れてください。
- わざわざカーソルを作成してループするのではなく、Oracleに手間のかかる作業を任せました。
後でOracleで実行できることはほとんどないため、コンマ区切りのリストを返したいと思うのはかなり不思議です。配列や、すべての名前を含む開いたカーソルのようなものを返す方が通常の場合があります。私は、この答えでは、あなたには自分が何であるかをする正当な理由があると思います。