2016-06-13 6 views
0

を閉じた後に開くには、そのようなこと:ORA-06511:PL/SQL:カーソルはすでに私が手続きしてパッケージを作成しているにも

PROCEDURE person_phone_data_load 
    IS 
     CURSOR cur_phone_info 
     is 
     SELECT itnpi.ROWID row_id, itnpi.* 
      from xx_TAL_NEWHIRE_PHONE_INT ITNPI, 
      xx_tal_newhire_employ_int emp 
      where 1 = 1 and ITNPI.STATUS in ('N', 'E') 
       and EMP.CANDIDATE_NUMBER=ITNPI.CANDIDATE_NUMBER 
      and BUSINESS_UNIT='APGEN BUSINESS GROUP' 
      ; 
/** 
select phone.ROWID row_id, phone.candidate_number, DECODE(phone.phone_type,'Work Phone','WORK','Home Phone','HOME','Cellular Phone','MOBILE',phone.phone_type) PHONE_TYPE, 
     case phone.phone_type 
      when 'Mobile Phone' then mobile_number 
      when 'Work Phone' then WORK_PHONE 
      when 'Home Phone' then home_number 
      end as phone_number 
from xx_tal_newhire_phone_int phone 
Where 1 = 1 And Phone.Status In ('N', 'E'); 
**/ 
     CURSOR lcu_get_person_id (p_candidate_number VARCHAR2) 
     IS 
     SELECT papf.person_id, papf.start_date 
      FROM per_all_people_f papf, per_people_extra_info ppei 
      WHERE papf.person_id = ppei.person_id 
       AND ppei.information_type = 'XXHR_TAL_NEWHIRE_READER' 
       AND ppei.pei_information1 = p_candidate_number 
       AND papf.effective_start_date = 
            (SELECT MAX (papf1.effective_start_date) 
             FROM per_all_people_f papf1 
             WHERE papf1.person_id = papf.person_id) 
     GROUP BY papf.person_id, papf.start_date; 

     CURSOR lcu_check_phone (p_personid NUMBER, p_phone_type VARCHAR2) 
     IS 
     SELECT phone_number 
      FROM per_phones 
      WHERE SYSDATE BETWEEN date_from AND NVL (date_to, '31-DEC-4712') 
      AND phone_type = p_phone_type 
      AND parent_id = p_personid; 

     lv_phone_type    VARCHAR2 (240); 
     ln_phone_type_excep  VARCHAR2 (2000); 
     an_phone_type_excep  VARCHAR2 (2000); 
     ln_phone_id    NUMBER; 
     ln_object_version_number NUMBER; 
     ld_ph_date_from   DATE; 
     ld_ph_date_to    DATE; 
     lv_phone_number   VARCHAR2 (100);  

     ln_person_id    NUMBER; 
     ln_phone_err_msg   VARCHAR2 (2000); 
     ln_person_excep   VARCHAR2 (2000); 
     an_person_excep   VARCHAR2 (2000); 
     lc_rec_status    VARCHAR2 (1); 
     ln_phoneno     NUMBER; 
     ln_start_date    DATE; 
    BEGIN 
     fnd_file.put_line (fnd_file.LOG, 
         '**********************************************' 
         ); 
     fnd_file.put_line (fnd_file.LOG, 
         '** New Hire Phone load Program Starts **' 
         ); 

     FOR phone_info_rec IN cur_phone_info 
     LOOP 
     BEGIN 
      lv_phone_type := NULL; 
      ln_phone_id := NULL; 
      ln_object_version_number := NULL; 
      ln_person_id := NULL; 
      ln_phone_err_msg := NULL; 
      ld_ph_date_from := TRUNC (SYSDATE); 
      ld_ph_date_to := NULL; 
      lv_phone_number := phone_info_rec.phone_number ; 

      ln_phone_type_excep := NULL; 
      ln_person_excep := NULL; 
      lc_rec_status := 'S'; 

      IF phone_info_rec.phone_type IS NOT NULL 
      THEN 
       lv_phone_type := 
        get_lookup_code ('PHONE_TYPE', phone_info_rec.phone_type); 

       IF lv_phone_type = 'NO_VALUE' 
       THEN 
        lc_rec_status := 'E'; 
        -- Could not decode the SEX for the Employee. 
        ln_phone_err_msg := 
         ln_phone_err_msg 
        || 'Invalid Phone Type for candidate_number: ' 
        || phone_info_rec.candidate_number 
        || ' # '; 
       END IF; 
      END IF; 

      IF phone_info_rec.candidate_number IS NOT NULL 
      THEN 
       ln_person_id := NULL; 

       OPEN lcu_get_person_id (phone_info_rec.candidate_number); 

       FETCH lcu_get_person_id 
       INTO ln_person_id, ln_start_date; 

       CLOSE lcu_get_person_id; 

       IF ln_person_id IS NULL 
       THEN 
        lc_rec_status := 'E'; 
        -- Employee Not Created for the Candidate Number. 
        ln_phone_err_msg := 
         ln_phone_err_msg 
        || 'Employee Record not created for the candidate_number: ' 
        || phone_info_rec.candidate_number 
        || ' # '; 
       ELSIF ln_person_id IS NOT NULL 
       THEN 
        OPEN lcu_check_phone (ln_person_id, lv_phone_type); 

        FETCH lcu_check_phone 
        Into Ln_Phoneno; 
    Close lcu_check_phone; 

     If Lcu_Check_Phone%Isopen Then 
         Close Lcu_Check_Phone; 
         END IF; 
        IF ln_phoneno = phone_info_rec.phone_number 
        Then 
        lc_rec_status := 'P'; 
        ln_phone_err_msg := 
          ln_phone_err_msg 
         || 'Phone already exists for the candidate_number: ' 
         || phone_info_rec.candidate_number 
         || ' # '; 


        END IF; 


       END IF; 
      ELSE 
       lc_rec_status := 'E'; 
       -- Candidate Number is NULL. 
       ln_phone_err_msg := 
        ln_phone_err_msg 
        || 'Candidate Number is NULL; So Could not find the Employee for Address creation'; 
      END IF; 

      IF lc_rec_status = 'S' 
      THEN 
       BEGIN 

        UPDATE xx_tal_newhire_phone_int iph 
        SET status = 'P', 
         error_msg = NULL 
        WHERE iph.ROWID = phone_info_rec.row_id; 

        COMMIT; 
        fnd_file.put_line 
        (fnd_file.LOG, 
         'Successfully Processed phone record for candidate_number: ' 
         || phone_info_rec.candidate_number 
        ); 
       EXCEPTION 
        WHEN OTHERS 
        THEN 
        ln_phone_err_msg := 
          'Phone API Error while processing candidate_number: ' 
         || phone_info_rec.candidate_number 
         || ' , ' 
         || SUBSTR (SQLERRM, 1, 150); 

        UPDATE xx_tal_newhire_phone_int iph 
         SET status = 'E', 
          error_msg = ln_phone_err_msg 
         WHERE iph.ROWID = phone_info_rec.row_id; 

        fnd_file.put_line 
         (fnd_file.LOG, 
          'Person API Error while processing candidate_number: ' 
         || phone_info_rec.candidate_number 
         || ' , ' 
         || SUBSTR (SQLERRM, 1, 150)||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE() 
         ); 
       END; 
      ELSE 
       UPDATE xx_tal_newhire_phone_int iph 
        SET status = lc_rec_status, 
         error_msg = ln_phone_err_msg 
       WHERE iph.ROWID = phone_info_rec.row_id; 
      END IF; 

      COMMIT; 
     EXCEPTION 
      WHEN OTHERS 
      THEN 
       ln_phone_err_msg := 
           'Phone Error : ' || SUBSTR (SQLERRM, 1, 150)||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(); 

       Update xx_Tal_Newhire_Phone_Int Iph 
        SET status = 'E', 
         error_msg = ln_phone_err_msg 
       WHERE iph.ROWID = phone_info_rec.row_id; 

       COMMIT; 
     END; 
     End Loop; 

     fnd_file.put_line (fnd_file.LOG, 
         '** New Hire Phone load Program Ends **' 
         ); 
    EXCEPTION 
     WHEN OTHERS 
     THEN 
     fnd_file.put_line (fnd_file.LOG, 
          'In phone main :' || SUBSTR (SQLERRM, 1, 150) 
          ); 
     ROLLBACK; 
    END person_phone_data_load; 

私が取得しています:"Phone Error : ORA-06511: PL/SQL: cursor already open

エラーをログに。これはカーソルlcu_check_phoneのためのものです。私は明示的にカーソルを閉じるためにif文を追加しました。それでも私はこのエラーが発生しています。

+1

このようなループ内のカーソルを開くことはベスト・アイデアではなく、本当に不要です。変数を選択するだけです(電話番号をl_phone_noから選択してください)。例外処理が問題になる可能性があります(カーソルを閉じることなく他のものがある場合) – tbone

+0

カーソルが行を返さない場合、lcu_check_phoneをLn_PhonenoにFETCHします。 NO_DATA_FOUND例外がスローされ、すべてのCLOSEコマンドはスキップされます。ループでカーソルを何回も開いたり閉じたりしないでください - カーソルを開閉するのはコストのかかる操作ですが、このコードは非常に遅くなります。 – krokodilko

+1

@kordirko - 実際にはそうではありません。明示カーソルの場合、データが返されないときは例外はスローされません –

答えて

2

私はあなたが持っている問題は、この

   OPEN lcu_check_phone (ln_person_id, lv_phone_type); 

       FETCH lcu_check_phone 
       Into Ln_Phoneno; 
       Close lcu_check_phone; 

電話番号が数値フィールドではないと思う - しかし、Ln_Phonenoは数として定義されます。フェッチ・ステートメントが処理される例外をスローしていますが、これはクローズ・ステートメントの両方をバイパスします。次の反復では、カーソルを再度開くことができません。

これらのネストされたループをすべて使用する場合は、例外ハンドラにcloseステートメントを入れる必要があります。

もう1つの方法は、モジュラ化することです。コードを分割するためにいくつかの小さな手順を使用します。各カーソルは1回の繰り返しの間だけ存在するため、スコープについてそれほど心配する必要はありません。それが意味をなさない...

1

オープン/クローズ/フェッチカーソルの問題を回避するには、可能であればカーソルループを使用します。あなたはループ(ループのように:他の言語からの各ループ)によって制御されているので、1回のフェッチではカーソルからすべての値をフェッチすることについて心配する必要はありません。私は標準のオープン/フェッチ/クローズを通常使用します。カーソルがデータをロードしていないときは、データが選択されていないときにNO_DATA_FOUNDをスローするための逆の処理で、たとえばNOTFOUNDフラグをtrueに設定してください。

関連する問題