1

次の関数は正常にコンパイルされます。ただし、無名 PL/SQL コードで関数を呼び出すと、呼び出しは失敗します。誰でも理由を提案できますか? 一致しない (新しい) データを挿入し、一致する (既存の) データを更新しようとしています。

Function Fn_Insert_Data_Using_Merge (p_Id in Number,
                                     p_fname in varchar2,
                                     p_mname in varchar2,
                                     p_lname in varchar2,
                                     p_birth_date in date) Return Boolean
Is
Begin
  Dbms_Output.put_line ('Inside the function Fn_Insert_Data_Using_Merge ...');
  Merge Into test_employee te
    using (select distinct p_Id, p_fname, p_mname, p_lname, p_birth_date
             from test_employee) temp_data
    on (te.first_name = temp_data.p_fname and
        te.middle_name = temp_data.p_mname and
        te.last_name = temp_data.p_lname)
    when matched then 
      update
        set first_name = p_fname,
            middle_name = p_mname,
            last_name = p_lname,
            run_status = 'Updated'
    when not matched then
      insert (id, first_name, middle_name, last_name, birth_date, run_status)
        values
             (p_id, p_fname, p_mname, p_lname, p_birth_date, 'Inserted');

  Dbms_Output.put_line ('Returning successfully from the function Fn_Insert_Data_Using_Merge ...');
  Return True;
Exception
  When Dup_Val_On_Index Then
    Dbms_Output.put_line ('The name already exists...Cannot insert again ..');
    Return False;
  When Others Then
    Dbms_Output.put_line ('Facing some critical error : ' || SQLERRM);
    Return False;
End Fn_Insert_Data_Using_Merge;
4

1 に答える 1

0

このエラーは、TEMP_DATA 抽出に P_LNAME という名前の列がないことを伝えようとしています。「p_lname」という名前の関数へのパラメーターがありますが、抽出では列のエイリアスを割り当てていないため、名前付きフィールドはありません。さらに (エラーの原因ではありませんが)、潜在的に多くの行を含むテーブルから DISTINCT を実行すると、関数パラメーターを USING 句の一時テーブルに取得するのに時間がかかります。SELECT...FROM DUAL を使用したほうがよいでしょう。MERGE ステートメントを次のように置き換えてみて、どうなるか教えてください。

Merge Into test_employee te
using (select p_Id as p_Id,
              p_fname as p_fname,
              p_mname as p_mname,
              p_lname as p_lname,
              p_birth_date as p_birth_date
         from dual) temp_data
on (te.first_name = temp_data.p_fname and
    te.middle_name = temp_data.p_mname and
    te.last_name = temp_data.p_lname)
when matched then 
  update
    set first_name = temp_data.p_fname,
        middle_name = temp_data.p_mname,
        last_name = temp_data.p_lname,
        run_status = 'Updated'
when not matched then
  insert (id,                first_name,             middle_name,
          last_name,         birth_date,             run_status)
    values
         (temp_data.p_id,    temp_data.p_fname,      temp_data.p_mname, 
          temp_data.p_lname, temp_data.p_birth_date, 'Inserted');

共有してお楽しみください。

于 2013-03-20T10:52:07.963 に答える