ORA-24381

In my pl/sql code i am doing the following
there is a cursor which select aroud 10,000 rows
open the cursor
loop
fetch the cursor in bulk collect 1000 limit
forall update in tableA
forall insert into tableB
forall insert into tableC
but the exception is coming in the First Insert not in the second ?
Why this is ocuuring any one can guide me?

When the first error occurs (in the first insert), PL/SQL exits, and raises the error message. It will not continue the loop. That's why it never reaches the second insert.
If you want to continue, you'll have to program it to do so.
Regards,
Rob.

Similar Messages

  • Getting error-ORA-24381: error(s) in array DML

    Hi i have written the following code to bulk insert into a database table.
    I am getting an error while returning the result of the bulk insert query into the collection
    I have tried to track it by using sql%bulk_exceptions.error_code.
    But the error code that it is showing is just 1.
    I trapped it using sqlerrm.
    and that is showing-error(s) in array DML
    What do i do?
    DECLARE
       CURSOR temp_rec_tap_cur
       IS
          SELECT *
            FROM temp_records_tap;
       TYPE temp_rec_tab IS TABLE OF temp_rec_tap_cur%ROWTYPE;
       v_test_tab   temp_rec_tab;
       v_rec_num    num_tab;
       v_filename   temp_records_tap.file_name%TYPE;
       v_error_code tap_reject.error_code%type;
       v_rej_value  tap_reject.field_rej%type;                      
       v_errors number;   
    BEGIN
       SELECT file_name
         INTO v_filename
         FROM table1
         WHERE ROWNUM<2;
       OPEN temp_rec_tap_cur;
       LOOP
          BEGIN
             FETCH temp_rec_tap_cur
             BULK COLLECT INTO v_test_tab LIMIT 1000;
             FORALL i IN v_test_tab.FIRST .. v_test_tab.LAST SAVE EXCEPTIONS
                INSERT INTO tapdetail_tapin
                     VALUES v_test_tab (i)
                  RETURNING record_num
                    BULK COLLECT INTO v_rec_num;
          EXCEPTION
             WHEN DUP_VAL_ON_INDEX
             THEN
                NULL;
             WHEN OTHERS
             THEN
             v_errors:=sql%bulk_exceptions.count;
             for i in 1..v_errors
             loop
             dbms_output.put_line(sql%bulk_exceptions(i).error_code);
             p3_errorlog ('TAPINDETAWARE', SQLERRM, v_filename);     
             end loop;
             END;
                --RAISE;
          EXIT WHEN temp_rec_tap_cur%NOTFOUND;
       END LOOP;
    INSERT INTO table2
    SELECT file_id, file_name, sender_pmn, recipient_pmn, call_date,
                 call_date_only, call_type, call_number, FIRST_RECORD,
                 service_type, service_code, home_bid, serve_bid,
                 chargeable_subs_type, imsi_min, msisdn_mdn, air_charges,
                 air_charges_sdr, air_time, national_call_charges,
                 national_call_charges_sdr, national_call_time,
                 international_call_charges, international_call_charges_sdr,
                 international_call_time, dir_assist_charges,
                 dir_assist_charges_sdr, dir_assist_time, other_charges,
                 other_charges_sdr, other_time, volume_charges,
                 volume_charges_sdr, volume_units, tot_charges, tot_charges_sdr,
                 tot_duration, state_tax, state_tax_sdr, local_tax,
                 local_tax_sdr, state_and_use_tax, state_and_use_tax_sdr, va_tax,
                 va_tax_sdr, other_tax, other_tax_sdr, charge_refund_indicator,
                 advised_charge_currency, advised_charge, advised_charge_sdr,
                 advised_charge_commission, advised_charge_commission_sdr,
                 exchange_rate, mcc, mnc, process_date, chargeable_units,
                 record_num, mscid,null,null,decode(call_type,0,'250',1,'251',5,'255'),null,'Duplicate Call'
                 from temp_records_tap
                 where record_num not in (select column_value from table(v_rec_num)) ;
    EXCEPTION
    WHEN OTHERS THEN
    p3_errorlog ('TAP', SQLERRM, v_filename);  
    END;Edited by: user8731258 on Sep 14, 2010 2:58 AM
    Edited by: user8731258 on Sep 14, 2010 3:01 AM

    What is the type declaration of num_tab and how is record_num defined?
    ORA-24381: error(s) in array DML
    Cause: One or more rows failed in the DML.indicates that you fail on the insert itself. Are the table definitions the same? Same primary/unique keys?
    Edited by: MBr on 14-Sep-2010 03:16

  • ORA-24381: error(s) in array DML - Reasons

    Hi all,
    Do you know when we could recieve this exceptions?
    I found one case - if we deal with FORALL and sparse collection.
    Any other cases?
    Thanks
    PS: We are talking for Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit
    :)

    Do you know when we could recieve this exceptions?e.g. all kind of constraint violations would raise this error:
    SQL> DECLARE
       TYPE emp_tab IS TABLE OF emp%ROWTYPE
          INDEX BY BINARY_INTEGER;
       e_tab   emp_tab;
    BEGIN
       e_tab (1).empno := 7900;
       FORALL i IN 1 .. 1 SAVE EXCEPTIONS
          INSERT INTO emp
               VALUES e_tab (i);
    EXCEPTION
       WHEN OTHERS
       THEN
          DBMS_OUTPUT.put_line (SQLERRM (SQLCODE));
    END;
    ORA-24381: error(s) in array DML
    ORA-00001: unique constraint (PK_EMP) violated

  • ORA-24381: error(s) in array DML

    Hi,
    I encountered error during mya testing. The script run thru several cases, until it encouter this error ORA-24381: error(s) in array DML.
    What could be the possible reason for this and can anyone give an idea to resolve this issue.
    Bulk collect was used with a limit of 1000.
    I used dblink to access database.
    Thanks in advance.

    The documentation tells you all about it: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/tuning.htm#sthref2201
    Regards,
    Rob.

  • Help with ORA 24381

    Hi all,
    I have a stored proecedure where I am supposed to load data into a table from multiple tables.
    I am using BULK COLLECT technique here. My data is loaded alright but in my status monitoring table (which records any errors that might occur) I am getting an entry after the data loads as:
    "ORA-24381: error(s) in array DML."
    Please suggest your inputs on what might be going wrong.
    Thank you.
    Edited by: Chaitanya on Oct 25, 2010 5:28 AM

    What version of Oracle?
    How much data are you trying to load?
    Can you post the code?

  • I am getting this "ORA-24381: error(s) in array DML error" in the code

    declare
    TYPE RehrCD_TYP IS TABLE OF wk_rehr_entity_hierarchy.wk_rehr_cd%TYPE;
    TYPE RehrParentCD_TYP IS TABLE OF wk_rehr_entity_hierarchy.wk_rehr_parent_cd%TYPE;
    TYPE RehrESSPath_TYP IS TABLE OF wk_rehr_entity_hierarchy.wk_rehr_ess_path%TYPE;
    L_levelRehrCD RehrCD_TYP;
    L_levelParentCD RehrParentCD_TYP;
    L_levelessPath RehrESSPath_TYP;
    L_cItem VARCHAR2(50) := 'PRC_Update_Level :';
    L_rows NUMBER DEFAULT 0;
    CURSOR Update_Level_CUR
         IS
    SELECT
    wk_rehr_cd
    ,wk_rehr_parent_cd
    ,wk_rehr_ess_path
    FROM
    wk_rehr_entity_hierarchy
    WHERE
    wk_rehr_ess_path LIKE '/ENTITY/ACTIVITY_USD%';
    BEGIN
    OPEN Update_Level_CUR;
    BEGIN
    LOOP
    FETCH Update_Level_CUR
    BULK COLLECT INTO
    L_levelRehrCD
    ,L_levelParentCD
    ,L_levelessPath
    LIMIT 10000;
    EXIT WHEN L_levelRehrCD.count = 0;
    dbms_output.put_line(1);
    FORALL i IN L_levelRehrCD.FIRST .. L_levelRehrCD.LAST SAVE EXCEPTIONS
    UPDATE
    wk_rehr_entity_hierarchy
    SET
    wk_rehr_ess_level = RPKG_Entity_Hierarchy.Get_Level(L_levelessPath(i))
    WHERE
    wk_rehr_cd = L_levelRehrCD(i)
    AND wk_rehr_parent_cd = L_levelParentCD(i);
    FOR j IN 1 .. L_levelRehrCD.COUNT
    LOOP
    L_rows := L_rows+ SQL%BULK_ROWCOUNT(j);
    END LOOP;
    END LOOP;
    CLOSE Update_Level_CUR;
    END;
    end;
    Please help me how to debug it?

    Just get rid of the whole looping approach - it's slow, inefficient and you don't need it.
    A single sql statement should always outperform looping code.
    Also, try to bring the logic of RPKG_Entity_Hierarchy.Get_Level inline to the SQL.
    If it's based on the column wk_rehr_ess_path then you might be able to use CONNECT BY or other methods to remove what is a bad practice and classic performance killer.
    I was going to suggest a MERGE statement like this:
    MERGE
    INTO  wk_rehr_entity_hierarchy wk
    USING (SELECT wk_rehr_cd
           ,      wk_rehr_parent_cd
           ,      RPKG_Entity_Hierarchy.Get_Level(wk_rehr_ess_path) lvl
           FROM   wk_rehr_entity_hierarchy
           WHERE  wk_rehr_ess_path LIKE '/ENTITY/ACTIVITY_USD%') xx
    ON    (wk.wk_rehr_cd        = xx.wk_rehr_cd
    AND    wk.wk_rehr_parent_cd = xx.wk_rehr_parent_cd)
    WHEN MATCHED THEN
           UPDATE
           SET    wk_rehr_ess_level = xx.lvl;But then I realised you're selecting from and updating the same table.
    Are you sure this isn't achievable in just a single update?
    UPDATE wk_rehr_entity_hierarchy
    SET    wk_rehr_ess_level = RPKG_Entity_Hierarchy.Get_Level(wk_rehr_ess_path)
    WHERE  wk_rehr_ess_path LIKE '/ENTITY/ACTIVITY_USD%';And then you can bring that function logic inline - much more efficient.

  • Unique constraint violation while updating a non PK column

    Hi,
    I seem to have found this strange error.
    What I try to do is bulk fetch a cursor in some table arrays. with limit of 1000
    Then using a forall and a save exceptions at the end
    I update a table with the values inside one of the table arrays.
    The column I update is not part of a PK
    I catch the error message: ORA-24381
    by using PRAGMA exception_init(dml_errors, -24381);
    and later on :
    WHEN dml_errors THEN
    errors := SQL%BULK_EXCEPTIONS.COUNT;
    FOR i IN 1..sql%BULK_EXCEPTIONS.count LOOP
    lr_logging.parameters:= 'index = ' || sql%BULK_EXCEPTIONS(i).error_index || 'error = ' ||Sqlerrm(-sql%BULK_EXCEPTIONS(i).error_code) ;
    END LOOP;
    I insert these errors in another table. and i get 956 errors
    first one is :
    index = 3error = ORA-00001: unique constraint (.) violated
    last one is
    index = 1000error = ORA-00001: unique constraint (.) violated
    How can this be.Since i don't update in a PKcolumn.
    FULL CODE IS:
    PROCEDURE Update_corr_values( as_checkdate_from IN VARCHAR2,
    as_checkdate_until IN VARCHAR2,
    as_market IN VARCHAR2
    IS
    LS_MODULE_NAME CONSTANT VARCHAR2(30) := 'update_values';
    lr_logging recon_logging.logrec;
    CURSOR lc_update IS
    SELECT /*+ORDERED*/c.rowid,c.ralve_record_id,d.value,c.timestamp,f.value
    FROM rcx_allocated_values a,
    rcx_allocated_values b,
    meter_histories e,
    rcx_allocated_lp_value c,
    rcx_allocated_lp_value d,
    counter_values f
    WHERE a.slp_type NOT IN ('S89', 'S88', 'S10', 'S30') --AELP
    AND b.slp_type IN ('S89', 'S88') --residu
    AND a.valid_from >= to_date(as_checkdate_from,'DDMMYYYY HH24:MI')
    AND a.valid_to <= to_date(as_checkdate_until,'DDMMYYYY HH24:MI')
    AND a.market = as_market
    AND a.market = b.market
    AND a.ean_sup = b.ean_sup
    AND a.ean_br = b.ean_br
    AND a.ean_gos = b.ean_gos
    AND a.ean_dgo = b.ean_dgo
    AND a.direction = b.direction
    AND a.valid_from = b.valid_from
    AND a.valid_to = b.valid_to
    AND c.ralve_record_id = a.record_id
    AND d.ralve_record_id = b.record_id
    AND c.TIMESTAMP = d.TIMESTAMP
    AND e.ASSET_ID = 'KCF.SLP.' || a.SLP_TYPE
    --AND f.timestamp between to_date(gs_checkdate_from,'ddmmyyyy') and to_Date(as_checkdate_until,'ddmmyyyy')
    AND e.SEQ = f.MHY_SEQ
    AND f.TIMESTAMP =c.timestamp - 1/24
    ORDER BY c.rowid;
    TYPE t_value IS TABLE OF RCX_ALLOCATED_LP_VALUE.VALUE%TYPE;
    TYPE t_kcf IS TABLE OF COUNTER_VALUES.VALUE%TYPE;
    TYPE t_timestamp IS TABLE OF RCX_ALLOCATED_LP_VALUE.TIMESTAMP%TYPE;
    TYPE t_ralverecord_id IS TABLE OF RCX_ALLOCATED_LP_VALUE.RALVE_RECORD_ID%TYPE;
    TYPE t_row IS TABLE OF UROWID;
    ln_row t_row :=t_row();
    lt_value t_value := t_Value();
    lt_kcf t_kcf := t_kcf();
    lt_timestamp t_timestamp := t_timestamp();
    lt_ralve t_ralverecord_id := t_ralverecord_id();
    v_bulk NUMBER := 1000;
    val number;
    kcf number;
    ralve number;
    times date;
    dml_errors EXCEPTION;
    errors NUMBER;
    PRAGMA exception_init(dml_errors, -24381);
    BEGIN
    --setting arguments for the logging record
    lr_logging.module := LS_MODULE_NAME;
    lr_logging.context := 'INFLOW_ALL_VALUES_PARTS';
    lr_logging.logged_by := USER;
    lr_logging.parameters := 'Date time started: ' || TO_CHAR(sysdate,'DD/MM/YYYY HH24:MI');
    -- log debugs
    recon_logging.set_logging_env (TRUE, TRUE);
    recon_logging.log_event(lr_logging,'D');
    OPEN lc_update;
    LOOP
    FETCH lc_update BULK COLLECT INTO ln_row,lt_ralve,lt_value,lt_timestamp,lt_kcf LIMIT v_bulk;
    FORALL i IN NVL(lt_value.first,1)..NVL(lt_value.last,0) SAVE EXCEPTIONS
    UPDATE RCX_ALLOCATED_LP_VALUE
    SET VALUE = VALUE * lt_value(i) * lt_kcf(i)
    WHERE rowid =ln_row(i);
    COMMIT;
    lt_value.delete;
    lt_timestamp.delete;
    lt_ralve.delete;
    lt_kcf.delete;
    ln_row.delete;
    EXIT WHEN lc_update%NOTFOUND;
    END LOOP;
    CLOSE lc_update;
    recon_logging.log_event(lr_logging,'D');
    lr_logging.parameters := 'Date time ended: ' || TO_CHAR(sysdate,'DD/MM/YYYY HH24:MI');
    recon_logging.log_event(lr_logging,'D');
    --to be sure
    COMMIT;
    EXCEPTION
    WHEN dml_errors THEN
    recon_logging.set_logging_env(TRUE,TRUE);
    lr_logging.module := 'updatevalues';
    lr_logging.context := 'exception';
    lr_logging.logged_by := USER;
    lr_logging.parameters := 'in dml_errors';
    recon_logging.log_event(lr_logging);
    errors := SQL%BULK_EXCEPTIONS.COUNT;
    lr_logging.parameters:=errors;
    recon_logging.log_event(lr_logging);
    lr_logging.parameters :=('Number of errors is ' || errors);
    --DBMS_OUTPUT.PUT_LINE('Number of errors is ' || errors);
    FOR i IN 1..sql%BULK_EXCEPTIONS.count LOOP
    lr_logging.parameters:= 'index = ' || sql%BULK_EXCEPTIONS(i).error_index || 'error = ' ||Sqlerrm(-sql%BULK_EXCEPTIONS(i).error_code) ;
    recon_logging.log_event(lr_logging);
    END LOOP;
    --recon_logging.set_logging_env(TRUE,TRUE);
    --recon_logging.log_event(lr_logging);
    commit;
    WHEN OTHERS THEN
    lr_logging.module := 'updatevalues';
    lr_logging.context := 'exception';
    lr_logging.logged_by := USER;
    recon_logging.set_logging_env(TRUE,TRUE);
    lr_logging.parameters := 'in others error=' || SQLERRM;
    recon_logging.log_event(lr_logging);
    commit;--to look which is truly the last (else only commit after 1000)
    --raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
    END Update_corr_values;

    Hi,
    No I didn't update a unique constraint.
    But I found out that there is a trigger that causes the unique constraint while updating in the table.
    Silly mistake.Didn't know there was a trigger there.
    Thx anyway.
    Greetz

  • Error while AD Connector Uninstallation in OIM11GR2

    Hi All,
    I am getting the following Error while uninstalling AD Connector.
    [ConnectorUninstall_Error.log],REMOVE_RESOURCE_EXCEPTION: Resource Object ->AD Group RemoveITResourceDef_EXCEPTION-->AD Group/XL_SP_RemoveITResourceDef/APP_INSTANCE ORA_CODE: 2292 ERROR CODE -->ORA-24381: error(s) in array DMLFrom ORA Error Stack -->ORA-06512: at "DEV_OIM.XL_PKG_REMOVEOBJECT", line 2978
    Thank you

    Hey,
    Sorry to revive this old thread, but I've got the exact same error. Have you found a solution ?
    Thanks,
    --jtellier                                                                                                                                                                                                                                                           

  • Error while data shifting from one table to another table

    i have two tables.
    in one table i dont have constraints.in anothe rtable i have constraints.
    my requiremnt is i have to shift data from unconstrained table to constrained table
    while shifting data any constaint violation is there system hasto raise error by specifying the error
    in below example it should be ename,esal values not null.
    i tried with save exception but it gives only error.i want error by mentiong that column names also ie ename,esal is not null
    if ename value only null then it should be give ename is null
    create table tablea (eno number(10), ename varchar2(20) not null, esal number(5) not null)
    create table tabl (eno number(10), ename varchar2(20) , esal number(5) )
    DECLARE
    TYPE tabl_tab IS TABLE OF tabl%rowTYPE;
    tab tabl_tab;
    -- create an exception handler for ORA-24381
    ERRORS NUMBER;
    dml_errors EXCEPTION;
    PRAGMA EXCEPTION_INIT (dml_errors, -24381);
    BEGIN
    SELECT *
    BULK COLLECT INTO tab
    FROM tabl
    WHERE rownum<=2;
    -- add '_SR' to the job_id of the most senior employees
    FORALL i IN tab.FIRST .. tab.LAST SAVE EXCEPTIONS
    insert into tablea values tab(i);
    EXCEPTION
    WHEN dml_errors
    THEN
    rollback ; --roll backs all the good records updation
    -- Now we figure out what failed and why.
    ERRORS := SQL%BULK_EXCEPTIONS.COUNT;
    DBMS_OUTPUT.put_line ('Number of statements that failed: ' || ERRORS);
    FOR i IN 1 .. ERRORS
    LOOP
    DBMS_OUTPUT.put_line ( 'Error #'
    || i
    || ' occurred during '
    || 'iteration #'
    || SQL%BULK_EXCEPTIONS (i).ERROR_INDEX
    DBMS_OUTPUT.put_line ( 'Error message is '
    || SQLERRM
    (-SQL%BULK_EXCEPTIONS (i).ERROR_CODE)
    END LOOP;
    END;
    how to implement that.

    it should give error as ename column is not null

  • A Bug in 11.1 array interface

    I have just encounter some code that runs fine in Oracle 9 to 10 but in 11.1 I am getting a different result.
    basically I have this SQL
    "INSERT INTO $table ( row_1, row_2, row_3) VALUES (?,?,?)"
    and bind all three to this array
    @var2 = (2,2,2,2,'s',2,2,2,2,2);
    using OCIBindByName and OCIBindDynamic and then execute them with
    OCIStmtExecute, with a mode (IN)
    of OCI_BATCH_ERRORS OCI_COMMIT_ON_SUCCESS (or 160)
    what happens is the commit does not happen in 11 but does happen in 9~10?
    Did something change in the execute in 11 or should I raise this up to a bug status??

    Ok here is a trace of the OCI Calls I use, and yes I the last one I give is a OCITransCommit
    st_execute_array INSERT count=10 (ARRAY(0x1a725c8) ARRAY(0x1a934c4) undef)
    OCIBindByName(876dad8,19cab00,8755e68,":p1",3,0,1,1,0,0,0,0,0,DATA_AT_EXEC)=SUCCESS
    OCIBindDynamic(876eda8,8755e68,19caadc, phs_in,19caadc,phs_out)=SUCCESS
    OCIBindByName(876dad8,1a27810,8755e68,":p2",3,0,1,1,0,0,0,0,0,DATA_AT_EXEC)=SUCCESS
    OCIBindDynamic(876ec68,8755e68,1a277ec,phs_in,1a277ec,phs_out)=SUCCESS
    OCIBindByName(876dad8,1a2bc18,8755e68,":p3",3,0,1,1,0,0,0,0,0,DATA_AT_EXEC)=SUCCESS
    OCIBindDynamic(876eb28,8755e68,1a2bbf4,phs_in,1a2bbf4,phs_out)=SUCCESS
    OCIStmtExecute(8755db0,876dad8,8755e68,10,0,0,0,160)=SUCCESS_WITH_INFO ->(OCI_BATCH_ERRORS|OCI_COMMIT_ON_SUCCESS)<--
    OCIAttrGet(876dad8,OCI_HTYPE_STMT,140f4ec,0,129,8755e68)=SUCCESS
    OCIErrorGet(8755e68,1,"<NULL>",140f48c,"ORA-24381: error(s) in array DML",1024,2)=SUCCESS
    OCIErrorGet(8755e68,2,"<NULL>",140f48c,"ORA-24381: error(s) in array DML",1024,2)=NO_DATA
    OCIAttrGet(876dad8,OCI_HTYPE_STMT,140f55c,0,73,8755e68)=SUCCESS
    st_execute_array 1 errors in batch.
    OCIHandleAlloc(8727940,140f578,OCI_HTYPE_ERROR,0,0)=SUCCESS
    OCIHandleAlloc(8727940,140f570,OCI_HTYPE_ERROR,0,0)=SUCCESS
    OCIParamGet(8755e68,2,876c3c0,140f578,0)=SUCCESS
    OCIAttrGet(876c968,OCI_HTYPE_ERROR,140f550,0,74,8755e68)=SUCCESS
    st_execute_array error in row 4.
    OCIErrorGet(876c968,1,"<NULL>",140f4cc,"ORA-01722: invalid number",1024,2)=SUCCESS
         OCIErrorGet(876c968,2,"<NULL>",140f4cc,"ORA-01722: invalid number",1024,2)=NO_DATA
    OCIHandleFree(876c3c0,OCI_HTYPE_ERROR)=SUCCESS
    OCIHandleFree(876c968,OCI_HTYPE_ERROR)=SUCCESS
    OCITransCommit(8755db0,8755e68,0)=SUCCESS
    st_execute_array warning: ORA-24381: error(s) in array DML (SUCCESS_WITH_
    INFO: error possibly near <*> indicator at char 56 in 'INSERT INTO test_ea( row_1, row_2,
    row_3) VALUES (:p1,:<*>p2,:p3)') [for Statement "INSERT INTO test_ea( row_1,  row_2, row_
    3) VALUES (?,?,?)"]
    and here is the code snipits but it is take out of a larger program so I will not run
    sb4
    phs_in(dvoid octxp, OCIBind bindp, ub4 iter, ub4 index,
         dvoid **bufpp, ub4 alenp, ub1 piecep, dvoid **indpp)
         phs_t phs = (phs_t)octxp;
    STRLEN phs_len;
    AV *tuples_av;
         SV *sv;
         AV *av;
         SV **sv_p;
         /* Check for bind values supplied by tuple array. */
         tuples_av = phs->imp_sth->bind_tuples;
         if(tuples_av) {
              /* NOTE: we already checked the validity in ora_st_bind_for_array_exec(). */
              sv_p = av_fetch(tuples_av, phs->imp_sth->rowwise ? (int)iter : phs->idx, 0);
              av = (AV*)SvRV(*sv_p);
              sv_p = av_fetch(av, phs->imp_sth->rowwise ? phs->idx : (int)iter, 0);
              sv = *sv_p;
              if(SvOK(sv)) {
              *bufpp = SvPV(sv, phs_len);
              phs->alen = (phs->alen_incnull) ? phs_len+1 : phs_len;
              phs->indp = 0;
              } else {
              *bufpp = SvPVX(sv);
              phs->alen = 0;
              phs->indp = -1;
    *alenp  = phs->alen;
    *indpp  = &phs->indp;
    *piecep = OCI_ONE_PIECE;
    if (!tuples_av && (index > 0 || iter > 0))
              croak(" Arrays and multiple iterations not currently supported (in %d/%d)", index,iter);
    return OCI_CONTINUE;
    sb4
    phs_out(dvoid octxp, OCIBind bindp,
         ub4 iter,     /* execution itteration (0...)     */
         ub4 index,     /* array index (0..)          */
         dvoid **bufpp,     /* A pointer to a buffer to write the bind value/piece.     */
         ub4 **alenpp,     /* A pointer to a storage for OCI to fill in the size     */
                   /* of the bind value/piece after it has been read.     */
         ub1 piecep,     / */
         dvoid **indpp,     /* Return a pointer to contain the indicator value which either an sb2     */
                   /* value or a pointer to an indicator structure for named data types.     */
         ub2 **rcodepp)     /* Returns a pointer to contains the return code.     */
    phs_t phs = (phs_t)octxp;     /* context */
    if (phs->desc_h) { /* a  descriptor if present  (LOBs etc)*/
              *bufpp  = phs->desc_h;
              phs->alen = 0;
    } else {
              SV *sv = phs->sv;
              if (SvTYPE(sv) == SVt_RV && SvTYPE(SvRV(sv)) == SVt_PVAV) {
              sv = av_fetch((AV)SvRV(sv), (IV)iter, 1);
              if (!SvOK(sv))
                        sv_setpv(sv,"");
              bufpp = SvGROW(sv, (size_t)(((phs->maxlen < 28) ? 28 : phs->maxlen)+1)/for null*/);
              phs->alen = SvLEN(sv);     /* max buffer size now, actual data len later */
    *alenpp = &phs->alen;
    *indpp  = &phs->indp;
    *rcodepp= &phs->arcode;
    *piecep = OCI_ONE_PIECE;
    return OCI_CONTINUE;
    static int
    do_bind_array_exec(sth, imp_sth, phs)
    SV *sth;
    imp_sth_t *imp_sth;
    phs_t *phs;
         dTHX;
    sword status;
    OCIBindByName_log(imp_sth->stmhp, &phs->bndhp, imp_sth->errhp,
    (text*)phs->name, (sb4)strlen(phs->name),
    0,
    phs->maxlen ? (sb4)phs->maxlen : 1, /* else bind "" fails */
    (ub2)phs->ftype, 0,
    NULL, /* ub2 alen_ptr not needed with OCIBindDynamic /
    0,
    0, /* max elements that can fit in allocated array */
    NULL, /* (ptr to) current number of elements in array */
    (ub4)OCI_DATA_AT_EXEC,
    status);
    if (status != OCI_SUCCESS) {
    oci_error(sth, imp_sth->errhp, status, "OCIBindByName");
    return 0;
    OCIBindDynamic_log(phs->bndhp, imp_sth->errhp,
    (dvoid *)phs, phs_in,
    (dvoid *)phs, phs_out, status);
    if (status != OCI_SUCCESS) {
    oci_error(sth, imp_sth->errhp, status, "OCIBindDynamic");
    return 0;
    return 1;
    static void
    init_bind_for_array_exec(phs)
    phs_t *phs;
         dTHX;
    if (phs->sv == &sv_undef) { /* first bind for this placeholder  */
    phs->is_inout = 0;
    phs->maxlen = 1;
    /* treat Oracle7 SQLT_CUR as SQLT_RSET for Oracle8 */
    if (phs->ftype==102)
    phs->ftype = 116;
    /* some types require the trailing null included in the length. */
    /* SQLT_STR=5=STRING, SQLT_AVC=97=VARCHAR */
    phs->alen_incnull = (phs->ftype==SQLT_STR || phs->ftype==SQLT_AVC);
    int
    st_execute_array(sth, imp_sth, tuples, tuples_status, columns, exe_count)
    SV *sth;
    imp_sth_t *imp_sth;
    SV *tuples;
    SV *tuples_status;
    SV *columns;
    ub4 exe_count;
         sword status, exe_status;
    int is_select = (imp_sth->stmt_type == OCI_STMT_SELECT);
    AV tuples_av, tuples_status_av, *columns_av;
    ub4 oci_mode;
    ub4 num_errs;
    int i,j;
    int autocommit = 1;
    SV **sv_p;
         phs_t **phs;
         SV *sv;
         AV *av;
    int param_count;
    char namebuf[30];
    STRLEN len;
    int outparams = (imp_sth->out_params_av) ? AvFILL(imp_sth->out_params_av)+1 : 0;
    tuples_av = (AV*)SvRV(tuples);
    /* Check the `columns' parameter. */
    if(SvTRUE(columns)) {
    if(!SvROK(columns) || SvTYPE(SvRV(columns)) != SVt_PVAV) {
    croak("ora_st_execute_array(): columns not an array peference.");
    columns_av = (AV*)SvRV(columns);
    } else {
    columns_av = NULL;
    /* Check the `tuples_status' parameter. */
    if(SvTRUE(tuples_status)) {
    if(!SvROK(tuples_status) || SvTYPE(SvRV(tuples_status)) != SVt_PVAV) {
         croak("ora_st_execute_array(): tuples_status not an array reference.");
    tuples_status_av = (AV*)SvRV(tuples_status);
    av_fill(tuples_status_av, exe_count - 1);
    /* Fill in 'unknown' exe count in every element (know not how to get
    individual execute row counts from OCI). */
    for(i = 0; (unsigned int) i < exe_count; i++) {
    av_store(tuples_status_av, i, newSViv((IV)-1));
    } else {
    tuples_status_av = NULL;
    /* Nothing to do if no tuples. */
    if(exe_count <= 0)
    return 0;
    param_count=c_NUM_PARAMS(imp_sth);/*returns the # of parameters on the imp_sth struct*/
         phs = safemalloc(param_count*sizeof(*phs));
    memset(phs, 0, param_count*sizeof(*phs));
         for(j = 0; (unsigned int) j < exe_count; j++) {
         sv_p = av_fetch(tuples_av, j, 0);
    if(sv_p == NULL) {
    Safefree(phs);
    croak("Cannot fetch tuple %d", j);
    sv = *sv_p;
    if(!SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVAV) {
    Safefree(phs);
    croak("Not an array ref in element %d", j);
    av = (AV*)SvRV(sv);
    for(i = 0; i < param_count; i++) {
    if(!phs) {
    SV **phs_svp;
    sprintf(namebuf, ":p%d", i+1);
    phs_svp = hv_fetch(imp_sth->all_params_hv,
    namebuf, strlen(namebuf), 0);
    if (phs_svp == NULL) {
    Safefree(phs);
    croak("Can't execute for non-existent placeholder :%d", i);
    phs[i] = (phs_t*)(void*)SvPVX(*phs_svp); /* placeholder struct */
    if(phs[i]->idx < 0) {
    Safefree(phs);
    croak("Placeholder %d not of ?/:1 type", i);
    init_bind_for_array_exec(phs[i]); /*bind the value */
    sv_p = av_fetch(av, phs[i]->idx, 0);
    if(sv_p == NULL) {
    Safefree(phs);
    croak("Cannot fetch value for param %d in entry %d", i, j);
                   sv = *sv_p;
         /*check to see if value sv is a null (undef) if it is upgrade it*/
                   if (!SvOK(sv))     {
                        if(SvUPGRADE(sv, SVt_PV)){} /* For GCC not to warn on unused result */
                   else {
              SvPV(sv, len);
         /* Find the value length, and increase maxlen if needed. */
         if(SvROK(sv)) {
         Safefree(phs);
         croak("Can't bind a reference (%s) for param %d, entry %d",
         neatsvpv(sv,0), i, j);
         if(len > (unsigned int) phs[i]->maxlen)
         phs[i]->maxlen = len;
         /* Do OCI bind calls on last iteration. */
         if( ((unsigned int) j ) == exe_count - 1 ) {
         if(!do_bind_array_exec(sth, imp_sth, phs[i])) {
         Safefree(phs);
         Safefree(phs);
    /* Store array of bind typles, for use in OCIBindDynamic() callback. */
    imp_sth->bind_tuples = tuples_av;
    imp_sth->rowwise = (columns_av == NULL);
    oci_mode = OCI_BATCH_ERRORS;
    if(autocommit)
    oci_mode |= OCI_COMMIT_ON_SUCCESS;
         OCIStmtExecute_log(imp_sth->svchp, imp_sth->stmhp, imp_sth->errhp,
    exe_count, 0, 0, 0, oci_mode, exe_status);
         imp_sth->bind_tuples = NULL;
    if (exe_status != OCI_SUCCESS) {
              oci_error(sth, imp_sth->errhp, exe_status, ora_sql_error(imp_sth,"OCIStmtExecute"));
    if(exe_status != OCI_SUCCESS_WITH_INFO)
    return -2;
    OCIAttrGet_log(imp_sth, &num_errs, 0, OCI_ATTR_NUM_DML_ERRORS, status);
    if(num_errs && tuples_status_av) {
    OCIError row_errhp, tmp_errhp;
    ub4 row_off;
    SV *err_svs[2];
    /*AV err_av;/
    sb4 err_code;
    err_svs[0] = newSViv((IV)0);
    err_svs[1] = newSVpvn("", 0);
    OCIHandleAlloc_log(imp_sth->envhp, &row_errhp, OCI_HTYPE_ERROR, status);
    OCIHandleAlloc_log(imp_sth->envhp, &tmp_errhp, OCI_HTYPE_ERROR, status);
    for(i = 0; (unsigned int) i < num_errs; i++) {
    OCIParamGet_log(imp_sth->errhp, OCI_HTYPE_ERROR,
    tmp_errhp, (dvoid *)&row_errhp,
    (ub4)i, status);
    OCIAttrGet_log(row_errhp, OCI_HTYPE_ERROR, &row_off, 0,
    OCI_ATTR_DML_ROW_OFFSET, imp_sth->errhp, status);
    sv_setpv(err_svs[1], "");
    err_code = oci_error_get(row_errhp, exe_status, NULL, err_svs[1], debug);
    sv_setiv(err_svs[0], (IV)err_code);
    av_store(tuples_status_av, row_off,
    newRV_noinc((SV *)(av_make(2, err_svs))));
    OCIHandleFree_log(tmp_errhp, OCI_HTYPE_ERROR, status);
    OCIHandleFree_log(row_errhp, OCI_HTYPE_ERROR, status);
    /* Do a commit here if autocommit is set, since Oracle
    doesn't do that for us when some rows are in error. */
    if(autocommit) {
    OCITransCommit_log(imp_sth->svchp, imp_sth->errhp,
    OCI_DEFAULT, status);
    if (status != OCI_SUCCESS) {
    oci_error(sth, imp_sth->errhp, status, "OCITransCommit");
    return -2;
    if(num_errs) {
    return -2;
    } else {
    ub4 row_count = 0;
              OCIAttrGet_stmhp_log(imp_sth, &row_count, 0, OCI_ATTR_ROW_COUNT, status);
    return row_count;

  • Error Handling for batch inserts

    Hi,
    Firstly, apologies if this has been asked before but I haven't been able to find the answer.
    I'm inserting a batch of rows, each of which could fail for different reasons (e.g. constraint, space, etc.). However, when I receive multiple failures and retrieve the error message it is always:
    ORA-24381: error(s) in array DML
    If I don't use the OCI_BATCH_ERRORS mode then it obviously only fails once and the correct error message is received for the first failure.
    Any suggestions as to how to get the real error would be appreciated.
    The code I'm using to lookup the errors is:
    OCIAttrGet (m_stmtHandle, OCI_HTYPE_STMT,
    &numErrors, 0, OCI_ATTR_NUM_DML_ERRORS,
    m_errorHandle);
    if (numErrors)
    OCIError *errhndl = NULL;
    ub4 row_off[100];
    for (int i = 0; i < numErrors; i++)
    OCIParamGet(m_errorHandle, OCI_HTYPE_ERROR,
    m_errorHandle,
    reinterpret_cast <void **> (&errhndl), i);
    OCIAttrGet (errhndl, OCI_HTYPE_ERROR, &row_off, 0,
    OCI_ATTR_DML_ROW_OFFSET, m_errorHandle);
    OCIErrorGet(errhndl, 1, NULL, &errorCode, errorText,
    maxErrorLen, OCI_HTYPE_ERROR);
    Thanks,
    Steven

    Hi,
    Please use the OCI forum for this question. This is for the C++ Call Interface.

  • Bulk exception problem

    DECLARE
    TYPE empid_tab IS TABLE OF emp1%ROWTYPE;
    emp_sr empid_tab;
    -- CREATE AN EXCEPTION HANDLER FOR ORA-24381
    ERRORS NUMBER;
    dml_errors EXCEPTION;
    v_err_no VARCHAR2 (200);
    v_err_message VARCHAR2 (200);
    PRAGMA EXCEPTION_INIT (dml_errors, -24381);
    BEGIN
    SELECT *
    BULK COLLECT INTO emp_sr
    FROM emp1
    WHERE hiredate > '30-MAY-80';
    FORALL i IN 1 .. emp_sr.COUNT SAVE EXCEPTIONS
    INSERT INTO emp_temp123
    VALUES emp_sr (i);
    --if any dupliacte records are inserting onto the emp_temp123 then it will give error as unique constraint violated
    -- IF ANY ERRORS OCCURRED DURING THE FORALL SAVE EXCEPTIONS,
    -- A SINGLE EXCEPTION IS RAISED WHEN THE STATEMENT COMPLETES.
    EXCEPTION
    WHEN dml_errors
    THEN -- NOW WE FIGURE OUT WHAT FAILED AND WHY.
    ERRORS := SQL%BULK_EXCEPTIONS.COUNT;
    DBMS_OUTPUT.put_line ('Number of statements that failed: ' || ERRORS);
    FOR i IN 1 .. ERRORS
    LOOP
    DBMS_OUTPUT.put_line ( 'Error #'
    || i
    || ' occurred during '
    || 'iteration #'
    || SQL%BULK_EXCEPTIONS (i).ERROR_INDEX
    DBMS_OUTPUT.put_line ( 'Error message is '
    || SQLERRM
    (-SQL%BULK_EXCEPTIONS (i).ERROR_CODE)
    v_err_no := SQL%BULK_EXCEPTIONS (i).ERROR_INDEX;
    v_err_message := SQLERRM (-SQL%BULK_EXCEPTIONS (i).ERROR_CODE);
    INSERT INTO errorlog
    (ID, MESSAGE
    VALUES (v_err_no, v_err_message
    COMMIT;
    END LOOP;
    END;
    ID     MESSAGE
    5     ORA-00001: unique constraint (.) violated
    6     ORA-00001: unique constraint (.) violated
    7     ORA-00001: unique constraint (.) violated
    8     ORA-00001: unique constraint (.) violated
    9     ORA-00001: unique constraint (.) violated
    10     ORA-00001: unique constraint (.) violated
    11     ORA-00001: unique constraint (.) violated
    12     ORA-00001: unique constraint (.) violated
    13     ORA-00001: unique constraint (.) violated
    3     ORA-00001: unique constraint (.) violated
    4     ORA-00001: unique constraint (.) violated
    here its only inserting the erros only but i want to insert the error records ie all columns of error record into another table named emp_err .how to do it.

    user10447332 wrote:
    here its only inserting the erros only but i want to insert the error records ie all columns of error record into another table named emp_err .how to do it.If Saubhik's solution is not the one you want you'll have to manually refer back to the collection for the records that have errors, then extract those values and do whatever you want with them.

  • Bulk collection doubt

    Hi All,
    I've one doubt regarding the bulk operations using the forall statement.
    Check below eample:
    CREATE TABLE emp_temp AS SELECT * FROM employees;
    DECLARE
    TYPE empid_tab IS TABLE OF employees.employee_id%TYPE;
    emp_sr empid_tab;
    -- create an exception handler for ORA-24381
    errors NUMBER;
    dml_errors EXCEPTION;
    PRAGMA EXCEPTION_INIT(dml_errors, -24381);
    BEGIN
    SELECT employee_id BULK COLLECT INTO emp_sr FROM emp_temp
    WHERE hire_date < '30-DEC-94';
    -- add '_SR' to the job_id of the most senior employees
    FORALL i IN emp_sr.FIRST..emp_sr.LAST SAVE EXCEPTIONS
    UPDATE emp_temp SET job_id = job_id || '_SR'
    WHERE emp_sr(i) = emp_temp.employee_id;
    -- If any errors occurred during the FORALL SAVE EXCEPTIONS,
    -- a single exception is raised when the statement completes.
    EXCEPTION
    WHEN dml_errors THEN -- Now we figure out what failed and why.
    errors := SQL%BULK_EXCEPTIONS.COUNT;
    DBMS_OUTPUT.PUT_LINE('Number of statements that failed: ' || errors);
    FOR i IN 1..errors LOOP
    DBMS_OUTPUT.PUT_LINE('Error #' || i || ' occurred during '||
    'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
    DBMS_OUTPUT.PUT_LINE('Error message is ' ||
    SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
    END LOOP;
    END;
    Here we update using bulk collect & the exceptions for each iterations are kept separately.
    In case, I want to know whether the sql statements in each array are executed separately or all the statements are executed in bulk?
    Thanks
    Deepak

    May this will answer it...
    FORALL - documentation

  • How to handle the bad record while using bulk collect with limit.

    Hi
    How to handle the Bad record as part of the insertion/updation to avoid the transaction.
    Example:
    I am inserting into table with LIMIT of 1000 records and i've got error at 588th record.
    i want to commit the transaction with 588 inserted record in table and log the error into
    error logging table then i've to continue with transaction with 560th record.
    Can anyone suggest me in this case.
    Regards,
    yuva

    >
    How to handle the Bad record as part of the insertion/updation to avoid the transaction.
    >
    Use the SAVE EXCEPTIONS clause of the FORALL if you are doing bulk inserts.
    See SAVE EXCEPTIONS in the PL/SQL Language doc
    http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/tuning.htm
    And then see Example 12-9 Bulk Operation that continues despite exceptions
    >
    Example 12-9 Bulk Operation that Continues Despite Exceptions
    -- Temporary table for this example:
    CREATE TABLE emp_temp AS SELECT * FROM employees;
    DECLARE
    TYPE empid_tab IS TABLE OF employees.employee_id%TYPE;
    emp_sr empid_tab;
    -- Exception handler for ORA-24381:
    errors NUMBER;
    dml_errors EXCEPTION;
    PRAGMA EXCEPTION_INIT(dml_errors, -24381);
    BEGIN
    SELECT employee_id
    BULK COLLECT INTO emp_sr FROM emp_temp
    WHERE hire_date < '30-DEC-94';
    -- Add '_SR' to job_id of most senior employees:
    FORALL i IN emp_sr.FIRST..emp_sr.LAST SAVE EXCEPTIONS
    UPDATE emp_temp SET job_id = job_id || '_SR'
    WHERE emp_sr(i) = emp_temp.employee_id;
    -- If errors occurred during FORALL SAVE EXCEPTIONS,
    -- a single exception is raised when the statement completes.
    EXCEPTION
    -- Figure out what failed and why
    WHEN dml_errors THEN
    errors := SQL%BULK_EXCEPTIONS.COUNT;
    DBMS_OUTPUT.PUT_LINE
    ('Number of statements that failed: ' || errors);
    FOR i IN 1..errors LOOP
    DBMS_OUTPUT.PUT_LINE('Error #' || i || ' occurred during '||
    'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
    DBMS_OUTPUT.PUT_LINE('Error message is ' ||
    SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
    END LOOP;
    END;
    DROP TABLE emp_temp;

  • Save Exceptions Limitation

    Hello Gurus,
    I have a problem with the Save Exceptions. I am using database 11g.
    When I am doing bulk insert I would like to insert the error records into a new table. But when I am inserting
    the error records I am getting the error "error:- ORA-00984: column not allowed here
    ORA-24381: error(s) in array DML".
    I am putting my code below.
    DECLARE
    CURSOR C_FRT2STORE IS
    SELECT ROWID,
    STORE_CD,
    MNR_CD,
    'FRT',
    DT,
    TO_DATE('31-DEC-2049'),
    FRT_FAC,
    TRUNC(SYSDATE),
    'ADMINUSR'
    FROM FRT2STORE;
    CURSOR C_FRT2STORE_EXC_TAB IS
    SELECT 'Y'
    FROM ALL_TABLES
    WHERE TABLE_NAME = 'FRT2STORE_EXC';
    TYPE STORE$MNR2CST_REC_TYPE IS RECORD
    (C_STORE$MNR2CST_ROWID VARCHAR2(100),
    C_STORE_CD STORE$MNR2CST.STORE_CD%TYPE,
    C_MNR_CD STORE$MNR2CST.MNR_CD%TYPE,
    C_CST_CD STORE$MNR2CST.CST_CD%TYPE,
    C_BEG_DT STORE$MNR2CST.BEG_DT%TYPE,
    C_END_DT STORE$MNR2CST.END_DT%TYPE,
    C_FAC NUMBER(13,3), --STORE$MNR2CST.FAC%TYPE,       
    C_AMT STORE$MNR2CST.AMT%TYPE,
    C_CUBIC_AMT STORE$MNR2CST.CUBIC_AMT%TYPE,
    C_LST_ACTN_DT STORE$MNR2CST.LST_ACTN_DT%TYPE,
    C_EMP_CD STORE$MNR2CST.EMP_CD%TYPE
    TYPE STORE$MNR2CST_TYPE IS TABLE OF STORE$MNR2CST_REC_TYPE
    INDEX BY PLS_INTEGER;
    STORE$MNR2CST_COL STORE$MNR2CST_TYPE;
    V_TOT_REC PLS_INTEGER := 0;
    V_FRT2STORE_EXC_TAB CHAR(1);
    V_TOT_REC_IN_STORE$MNR2CST PLS_INTEGER;
    V_ERR_REC PLS_INTEGER;
    BULK_ERRORS EXCEPTION;
    PRAGMA EXCEPTION_INIT (BULK_ERRORS, -24381);
    BEGIN
    --GETTING DATA FROM FRT2STORE TABLE AND INSERTING INTO THE STORE$MNR2CST TABLE
    SELECT COUNT(1)
    INTO V_TOT_REC_IN_STORE$MNR2CST
    FROM STORE$MNR2CST ;
    IF V_TOT_REC_IN_STORE$MNR2CST = 0 THEN
    OPEN C_FRT2STORE;
    LOOP
    FETCH C_FRT2STORE BULK COLLECT INTO STORE$MNR2CST_COL LIMIT 1000;
    EXIT WHEN STORE$MNR2CST_COL.COUNT = 0;
    V_TOT_REC := STORE$MNR2CST_COL.COUNT;
    IF V_TOT_REC > 0 THEN
    BEGIN
    FORALL I IN STORE$MNR2CST_COL.FIRST..STORE$MNR2CST_COL.LAST SAVE EXCEPTIONS
    INSERT INTO STORE$MNR2CST
    (STORE_CD,
    MNR_CD,
    CST_CD,
    BEG_DT,
    END_DT,
    FAC,
    AMT,
    CUBIC_AMT,
    LST_ACTN_DT,
    EMP_CD
    VALUES
    (STORE$MNR2CST_COL(I).C_STORE_CD,
    STORE$MNR2CST_COL(I).C_MNR_CD,
    STORE$MNR2CST_COL(I).C_CST_CD,
    STORE$MNR2CST_COL(I).C_BEG_DT,
    STORE$MNR2CST_COL(I).C_END_DT,
    STORE$MNR2CST_COL(I).C_FAC,
    STORE$MNR2CST_COL(I).C_AMT,
    STORE$MNR2CST_COL(I).C_CUBIC_AMT,
    STORE$MNR2CST_COL(I).C_LST_ACTN_DT,
    STORE$MNR2CST_COL(I).C_EMP_CD
    COMMIT;
    EXCEPTION WHEN BULK_ERRORS THEN
    OPEN C_FRT2STORE_EXC_TAB;
    FETCH C_FRT2STORE_EXC_TAB INTO V_FRT2STORE_EXC_TAB;
    IF C_FRT2STORE_EXC_TAB%NOTFOUND THEN
    EXECUTE IMMEDIATE ('CREATE TABLE FRT2STORE_EXC AS SELECT * FROM FRT2STORE WHERE 1 = 2');
    END IF;
    CLOSE C_FRT2STORE_EXC_TAB;
    FOR J IN 1..SQL%BULK_EXCEPTIONS.COUNT
    LOOP
    V_ERR_REC := SQL%BULK_EXCEPTIONS(J).ERROR_INDEX;
    EXECUTE IMMEDIATE 'INSERT INTO FRT2STORE_EXC (STORE_CD,MNR_CD,FRT_FAC,DT) VALUES ('
    ||STORE$MNR2CST_COL(V_ERR_REC).C_STORE_CD||','
    ||STORE$MNR2CST_COL(V_ERR_REC).C_MNR_CD||','
    ||STORE$MNR2CST_COL(V_ERR_REC).C_FAC||','
    ||STORE$MNR2CST_COL(V_ERR_REC).C_BEG_DT||')';
    END LOOP;
    COMMIT;
    END;
    STORE$MNR2CST_COL.DELETE;
    END IF;
    END LOOP;
    CLOSE C_FRT2STORE;
    END IF;
    COMMIT;
    EXCEPTION WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('error:- '||SQLERRM);
    END ;
    Could any one tell me how to achive this requirment.
    Thanks,
    Sun

    1. Please format your code using the code tags.
    2. You should never need to code create tables like this "EXECUTE IMMEDIATE ('CREATE TABLE FRT2STORE....". This is often seen when creating temporary tables in non-Oracle database but is a misunderstanding in how to do things in Oracle. You should create them outside of your plsql as permanent objects.
    3. In your example, you should not need dynamic sql like this "EXECUTE IMMEDIATE 'INSERT INTO FRT2STORE_EXC...."
    4. In 10gR2 / 11g, DML Error Logging might be a better solution
    http://www.oracle.com/technology/oramag/oracle/06-mar/o26performance.html

Maybe you are looking for