1

渡されたパラメーターにマネージャーIDが依存するすべての従業員について、従業員の名前を文字列形式で返す必要があります。関数をコンパイルするとエラーが発生します。機能コードは次のとおりです。

create or replace function Employee(v_manid IN employees.manager_id%type) 
return varchar2
AS
cursor cur_emp is select last_name from employees where manager_id = v_manid;
v_names varchar2(10);
begin
for emp_rec in cur_emp
loop
v_name = v_name || emp_rec.last_name ||', ';
end loop;
return v_name
end;
/

エラーは次のとおりです。

エラー(8,8):PLS-00103:次のいずれかを予期しているときに記号"="が発生しました::=。(@%; Error(8,44):PLS-00103:次のいずれかを予期しているときに記号 ";"が発生しました:)、*&-+/modの剰余remおよびまたは||

誰かがこれで私を助けることができますか?

4

3 に答える 3

5

他の回答で述べられているように、関数がコンパイルされない理由は3つあります。

  1. 変数を宣言し、v_namesそれをとして参照していv_nameます。
  2. PL / SQLの代入演算子は:=、等式演算子を使用しています=
  3. 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;
/

私が行った他のいくつかの変更に注意してください:

  1. 関数パラメーターに変数とは異なる文字を付加して、どちらがどちらであるかを明確にします。
  2. その特定のマネージャーのデータがないことに対処するために、いくつかの例外処理を追加します。
  3. ,私がNULLを返すデータがなかったら、あなたは戻ったでしょう。代わりにコンマを返したい場合は、これを例外の中に入れてください。
  4. わざわざカーソルを作成してループするのではなく、Oracleに手間のかかる作業を任せました。

後でOracleで実行できることはほとんどないため、コンマ区切りのリストを返したいと思うのはかなり不思議です。配列や、すべての名前を含む開いたカーソルのようなものを返す方が通常の場合があります。私は、この答えでは、あなたには自分が何であるかをする正当な理由があると思います。

于 2012-11-22T08:21:21.333 に答える
3

注意すべき点がいくつかあります。

  • として宣言されますv_namesが、として使用されますv_name

  • 割り当ては次のようになりますv_name := v_name || emp_rec.last_name || ', ';

  • v_nameサイズが10で宣言されていると、小さすぎて実行時にエラーが発生するため、次のように宣言できます。

    v_name employees.last_name%TYPE;

次のように関数を作成できます

CREATE OR REPLACE FUNCTION employee (v_manid IN employees.manager_id%TYPE)
        RETURN VARCHAR2
       AS
        v_name  employees.last_name%TYPE;
        CURSOR cur_emp
        IS
            SELECT  last_name
              FROM  employees
             WHERE  manager_id = v_manid;
    BEGIN
        FOR emp_rec IN cur_emp
        LOOP
            v_name := v_name || emp_rec.last_name || ', ';
        END LOOP;

        RETURN v_name;
    END;
/
于 2012-11-22T04:54:28.003 に答える
1

私はあなたが 好き:=の代わりに使うべきだと思います=

v_name := v_name || emp_rec.last_name ||', ';

同様 ;の最後にセミコロンを追加する必要があるもう1つのことreturn v_namereturn v_name;

于 2012-11-22T04:32:39.117 に答える