FORALL stmt

Hi there,
I 'm studying FORALL statement and I ran into a problem I don't understand.
I have a table:
create table employee_1 as select employee_id, last_name,first_name
from employees
where 1=2;
And I want to move the data from HR employees to it using FORALL.
How can I redo this, so I don't have to use dynamic SQL?
declare
type ln_type is table of varchar2(30)
index by pls_integer;
type id_type is table of number
index by pls_integer;
ln ln_type;
fn ln_type;
eid id_type;
v_counter integer:=0;
begin
for r in (select employee_id,last_name, first_name
from employees where employee_id >200)
loop
v_counter:=v_counter+1;
ln(v_counter):=r.last_name;
fn(v_counter):=r.first_name;
eid(v_counter):=r.employee_id;
end loop;
forall i in eid.first..eid.last
execute immediate
'insert into employees_1(employee_id,last_name,first_name)
values (:1,:2,:3)'
using eid(i),ln(i),fn(i);
end;
This works, but I want to write it with regular SQL (if that is possible?)
I tried it like this:
forall i in eid.first..eid.last
insert into employees_1(employee_id,last_name,first_name)
values (eid(i),ln(i),fn(i));
end;
but I keep getting
PLS-00430: FORALL iteration variable I is not allowed in this context
I googled the error and I got
Cause: FORALL iteration variable can only be used as a
subscript. It cannot be used directly or as a part of an
expression.
Action: Use FORALL variable only as a collection subscript.
Can somebody explain this to me in a more understandable manner?
And fix my code for if possible!
All help appreciated

Jana Kralova wrote:
By the way, you wouldn't by any chance know why I am not able to use
individual column table types. This is a good one. There is nothing wrong with using individual column table types, just using built-in function name as variable name can sometimes fool you quite a bit:
SQL> declare
  2      type ln_type is table of varchar2(30)
  3        index by pls_integer;
  4      type id_type is table of number
  5        index by pls_integer;
  6      ln ln_type;
  7      fn ln_type;
  8      eid id_type;
  9      v_counter integer:=0;
10  begin
11      select  employee_id,
12              last_name,
13              first_name
14        bulk collect
15        into eid,
16             ln,
17             fn
18        from hr.employees
19        where employee_id >200;
20        v_counter:=v_counter+1;
21        forall i in eid.first..eid.last
22          insert into employees_1(employee_id,last_name,first_name)
23          values (eid(i),ln(i),fn(i));
24  end;
25  /
        values (eid(i),ln(i),fn(i));
ERROR at line 23:
ORA-06550: line 23, column 27:
PLS-00430: FORALL iteration variable I is not allowed in this context
SQL> declare
  2      type ln_type is table of varchar2(30)
  3        index by pls_integer;
  4      type id_type is table of number
  5        index by pls_integer;
  6      lnm ln_type;
  7      fn ln_type;
  8      eid id_type;
  9      v_counter integer:=0;
10  begin
11      select  employee_id,
12              last_name,
13              first_name
14        bulk collect
15        into eid,
16             lnm,
17             fn
18        from hr.employees
19        where employee_id >200;
20        v_counter:=v_counter+1;
21        forall i in eid.first..eid.last
22          insert into employees_1(employee_id,last_name,first_name)
23          values (eid(i),lnm(i),fn(i));
24  end;
25  /
PL/SQL procedure successfully completed.
SQL> Your problem is LN(I) is interpreted as built-in natural logarithm function LN with I as function parameter.
SY.

Similar Messages

  • Please Ignore

    Guys,
    SQL> select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
    PL/SQL Release 10.2.0.4.0 - Production
    CORE 10.2.0.4.0 Production
    TNS for Solaris: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - Production
    Problem: I wrote a procedure to parse a varchar2 field of a table.
    It contains long strings. These strings are put into that column
    by a java application. The procedure has an inline view which retrieve
    records containing certain string pattern. The table has about
    2 million records. After procedure gets the strings from the
    inline view; for a particular pattern I found that inline view should
    be containing 600k records; the Oracle regex function parses to put
    the relevant parts into separate columns. At first, I thought, may be
    inline view is the culprit. So, I created a staging table and ran my
    procedure on it; I created a BTree index on the column. But, no results.
    Then I thought DISTINCT keyword is the problem. Removed it, but still procedure
    doesn't populate the tables. I am not sure what is going on. Even DBAs are
    not sure. I told them to create an index on varchar2 column of original table. They have
    created it but no improvement. Would someone please advice? I am new to sql tuning.
    Is there any tutorial which explains with examples about sql tuning - I mean,
    I am looking for something like
    1. explain plan - What every field means?
    2. dbms_prof - How to readthe output?
    3. trace - how to use it? etc.
    Thanks in advance!
    CREATE OR REPLACE PROCEDURE prc_parse
    IS
    --  Purpose: Procedure to parse column of table
                 to retrieve crit, points,
                 comment, morecomment and
                 overallcomment.
    --  MODIFICATION HISTORY
    --  Person          Date       Comments
    TYPE src_crit IS TABLE OF subtable.column1%TYPE;
    TYPE src_points IS TABLE OF subtable.column1%TYPE;
    TYPE src_comment IS TABLE OF subtable.column1%TYPE;
    TYPE src_morecomment IS TABLE OF subtable.column1%TYPE;
    TYPE src_overall_comment IS TABLE OF subtable.column1%TYPE;
    src_crit_array   src_crit;
    src_points_array   src_points;
    src_comment_array   src_comment;
    src_morecomment_array   src_morecomment;
    src_overall_comment_array   src_overall_comment;
    CURSOR cur_latest
    IS
    SELECT   DISTINCT
             TRIM(REPLACE(REPLACE(SUBSTR(REGEXP_SUBSTR(string,'Crit:</strong>[^<]+', 1, level), 15),CHR(13),''),CHR(10),'')) crit,
             TRIM(REPLACE(REPLACE(SUBSTR(REGEXP_SUBSTR(string,'points [^\)]+', 1, level), 8),CHR(13),''),CHR(10),'')) points,
             TRIM(REPLACE(REPLACE(SUBSTR(REGEXP_SUBSTR(string,'\):[^<]+', 1, level), 3),CHR(13),''),CHR(10),'')) comment,
             TRIM(REPLACE(REPLACE(SUBSTR(REGEXP_SUBSTR(string,'blockquote>[^<]+', 1, level), 12),CHR(13),''),CHR(10),'')) morecomment,
             TRIM(REPLACE(REPLACE(SUBSTR(string, INSTR(string, '>', -1) + 1),CHR(13),''),CHR(10),'')) overallcomment
      FROM   (SELECT  column1 string
                 FROM subtable
                WHERE column1 LIKE '<strong>Crit:</strong>%'
    CONNECT BY LEVEL <= (LENGTH(string) - LENGTH(REPLACE(string, 'Crit:')))/5;
    BEGIN
        OPEN cur_latest;
        LOOP
           FETCH cur_latest
           BULK COLLECT INTO   src_crit_array,
                               src_points_array,
                               src_comment_array,
                               src_morecomment_array,
                               src_overall_comment_array
                        LIMIT 100;
            FORALL i in 1 .. src_crit_array.COUNT
                INSERT INTO test_parse_table1 (
                                                        crit,
                                                        points,
                                                        comment,
                                                        morecomment
                                               VALUES (
                                                        src_crit_array(i),
                                                        src_points_array(i),
                                                        src_comment_array(i),
                                                        src_morecomment_array(i)
                FORALL i in 1 .. src_crit_array.COUNT         
                INSERT INTO test_parse_table2 (
                                                     overallcomment
                                           VALUES (
                                                     src_overallcomment_array(i)
           EXIT WHEN cur_latest%NOTFOUND;
              COMMIT;
        END LOOP;
       COMMIT;
    EXCEPTION
      WHEN OTHERS THEN
        ROLLBACK;
        DBMS_OUTPUT.PUT_LINE('Error:'||sqlerrm);
        COMMIT;
    END;
    /Edited by: abyss on Sep 19, 2010 6:03 PM
    Edited by: abyss on Oct 1, 2010 9:27 AM

    Abyss,
    You can do multiple inserts using the FORALL stmt, I dont see any thing wrong with that code bit.
    I tried it with the below eg & it worked fine for me ...
    create table TBL_TEST
      col1 NUMBER,
      col2 NUMBER,
      col3 CHAR(1)
    create table tbl_test2
    as
    select t.col1, t.col2 from tbl_test t where 1=2;
    create table tbl_test3
    as
    select t.* from tbl_test t where 1=2;
    declare
    type lt_prod_row is table of tbl_test.col1%type;
    type lt_sup_row is table of tbl_test.col2%type;
    type lt_pri_row is table of tbl_test.col3%type;
    ltc1r lt_col1_row;
    ltc2r lt_col2_row;
    ltc3r lt_col3_row;
    begin
    select tbl.col1, tbl.col2, tbl.col3
    bulk collect into ltc1r, ltc2r, ltc3r
    from tbl_test tbl;
    dbms_output.put_line(ltc1r.count);
    forall i in 1..ltc1r.count
            insert into tbl_test3 values (ltc1r(i), ltc2r(i), ltc3r(i));
    forall i in 1..ltc1r.count
            insert into tbl_test2 (col1, col2) values (ltc1r(i), ltc2r(i));
    end;Which line of your code are you getting the error ?

  • GETTING ERROR INVALID IDETIFIER

    NEED HELP ASAP!!!!!!
    ERROR MARKED AGAINT THE LINE...SEE THE LAST FEW LINWS FRM FORALL STMT
    declare
    type summary_upd_tab is table of summary%rowtype;
    summary_upd_var summary_upd_tab;
    begin
    select
    user_id,
    min(start_time_utc),
    max(end_time_utc),
    sum(duration_seconds),
    sum(upload_bytes),
    sum(download_bytes),
    sum(upload_bytes)+sum(download_bytes),
    null,
    null,
    null,
    type_of_summary,
    ispeak,
    null
    --TOTALDISCOUNT
    bulk collect into summary_upd_var
    from aaa_sessions a
    -- hsin_plan_details hpd
    group by user_id,ispeak,type_of_summary;
    forall i in summary_upd_var.first..summary_upd_var.last
    update summary s
    set
    start_date=DECODE((summary_upd_var.start_date-s.start_date)-abs(summary_upd_var.start_date-s.start_date),0,s.start_date,summary_upd_var.start_date),
    end_date=decode((summary_upd_var.end_time_utc-s.end_date)-abs(summary_upd_var.end_time_utc-s.end_date),0,summary_upd_var.end_time_utc,s.end_date),
    total_duration=s.TOTAL_DURATION+summary_upd_var.total_duration,
    total_upload=s.total_upload+summary_upd_var.total_upload,
    total_download=s.total_download+summary_upd_var.total_download
    --total_traffic=s.total_upload+summary_upd_var.total_upload+s.total_download+summary_upd_var.total_download
    where
    summary.user_id=summary_upd_var.user_id
    and
    summary.ispeak=summary_upd_var.ispeak
    and
    summary.TYPE_OF_SUMMARY=summary_upd_var.TYPE_OF_SUMMARY; -------INVALID IDENTIFIER????this column is present in the tablle...then why??
    end;

    user8731258 wrote:
    this is how my query looks like...
    bu t i am nt very clear as to how correlated update would work?Here is a simple example of the workings:
    SQL> create table t
      2  as
      3  select rownum id
      4       , rownum + 2 tid
      5    from all_objects
      6   where rownum <= 5
      7  /
    Table created.
    SQL> create table s
      2  as
      3  select *
      4    from t
      5  /
    Table created.
    SQL>
    SQL> update s
      2     set tid = tid * 2
      3  /
    5 rows updated.
    SQL>
    SQL> select *
      2    from t
      3  /
            ID        TID
             1          3
             2          4
             3          5
             4          6
             5          7
    SQL> select *
      2    from s
      3  /
            ID        TID
             1          6
             2          8
             3         10
             4         12
             5         14
    SQL>
    SQL>
    SQL> update t
      2    set (id, tid) = (select s.id, s.tid
      3                   from s
      4                   where s.id = t.id)
      5  ;
    5 rows updated.
    SQL> select *
      2    from t
      3  /
            ID        TID
             1          6
             2          8
             3         10
             4         12
             5         14As you can see it works as advertised....
    user8731258 wrote:
    I still want to use collection..so plz tell me a workaround for this reference error!!!!Why?... the UPDATE works fine, anyway ...follow the links I posted before

  • Binds collections and forall statement

    version 9.2.0.6
    I would like to make this more dynamic in that the collection cList can be used only once and be used by all bind variables. The variable stmt would be dynamically generated in that case it would insert into any number of tables.
    Can this be done?
    Is this feature available in a newer version of Oracle?
    create table d2 nologging as
    select
      rownum rn
      ,substr(dbms_random.string('x',5),1,10) v1
      ,sysdate d1
      ,round(dbms_random.value(1,10)) n1
      ,substr(dbms_random.string('x',5),1,10) v2
      ,rpad(' ',4000,' ') as concat
    from dual connect by level <= 100;
    -- no rows for our test
    create table d3 nologging as
    select
    from d2 where 1 = 2;
    -- setup for our test
    update d2
    set image = rpad(nvl(to_char(rn),' '),10,' ')                                
             || rpad(nvl(v1,' '),20,' ')                                         
             || rpad(nvl(to_char(d1,'DD-MON-YYYY HH24:MI:SS'),' '),34,' ')       
             || rpad(nvl(to_char(n1),' '),10,' ')                                
             || rpad(nvl(v2,' '),10,' ')                                         
    -- test got all locations right
    select
      to_number(rtrim(substr(image,1,10)))
      ,rtrim(substr(image,11,20))
      ,to_date(rtrim(substr(image,30,34)),'DD-MON-YYYY HH24:MI:SS')
      ,to_number(rtrim(substr(image,65,10))) AS n1
      ,rtrim(substr(image,75,10))
    from d2;
    -- here is where we do the work
    declare
    type charList is table of varchar2(4000);
    cList charList;
    d2l d2_list;
    errors NUMBER;
    dml_errors EXCEPTION;
    PRAGMA exception_init(dml_errors, -24381);
    sqlStmt varchar2(32000);
    cursor cur is select image from d2;
    bcLimit number := 23;
    begin
    sqlStmt := 'insert into d3 (rn,v1,d1,n1,v2)'
             || 'values (to_number(rtrim(substr(:a,1,10)))
                        ,rtrim(substr(:a,11,20))
                        ,to_date(rtrim(substr(:a,30,34)),''DD-MON-YYYY HH24:MI:SS'')
                        ,to_number(rtrim(substr(:a,65,10)))
                        ,rtrim(substr(:a,75,10)))';
    open cur;
    loop
      fetch cur bulk collect into cList limit bcLimit;
      exit when cList.count = 0;
      begin
       -- very very unfortunately the code is unable to have one using clause variable be applied to all bind variables
       -- note the number of cList uses having the bind variables all name the same does not help
       -- using only one gets a ORA-1008 error  :(
       FORALL i IN cList.FIRST..cList.LAST SAVE EXCEPTIONS execute immediate sqlstmt using cList(i),cList(i),cList(i),cList(i),cList(i);
       -- FORALL i IN cList.FIRST..cList.LAST SAVE EXCEPTIONS execute immediate sqlstmt using cList(i); --< DOES NOT WORK :(  I WISH IT WOULD!
      EXCEPTION
       WHEN dml_errors THEN
         errors := SQL%BULK_EXCEPTIONS.COUNT;
         dbms_output.put_line('number of errors is ' || 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('Could not insert ' || cList(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX));
          dbms_output.put_line(SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
         END LOOP;
      end;
    end loop;
    close cur;
    dbms_output.put_line('h2');
    end;
    /

    The CREATE TABLE you post for table D2 has no column called 'image'. It would help somewhat if you posted a working example.
    Also I am not clear why the INSERT INTO D3 statement in the anonymous block needs to be dynamic.

  • Not enough values for FORALL

    Hi,
    I have written this procedure and I am getting
    LINE/COL ERROR
    69/5 PL/SQL: SQL Statement ignored
    83/11 PL/SQL: ORA-00947: not enough values
    CREATE OR REPLACE PROCEDURE f_t_s (P_F IN VARCHAR2)
    IS
    TYPE quote_cols_rt IS RECORD
    twitter_gid twitter.twitter_gid%TYPE,
    twitter_xid twitter.twitter_xid%TYPE,
    origin_location_type twitter.origin_location_type%TYPE,
    destination_location_type twitter.destination_location_type%TYPE,
    is_hazardous twitter.is_hazardous%TYPE,
    perspective twitter.perspective%TYPE,
    twitter_option twitter.twitter_option%TYPE,
    servprov_gid twitter.servprov_gid%TYPE,
    origin_search_value twitter.origin_search_value%TYPE,
    destination_search_value twitter.destination_search_value%TYPE,
    domain_name twitter.domain_name%TYPE,
    is_customer_rates_only twitter.is_customer_rates_only%TYPE
    TYPE twitter_cols_tt IS TABLE OF twitter_cols_rt INDEX BY PLS_INTEGER;
    twitter_cols_t twitter_cols_tt;
    BEGIN
    SELECT all_spec twitter_gid,
    SUBSTR(all_spec,7) twitter_xid,
    'location_code' origin_location_type,
    'location_code' destination_location_type,
    'N' is_hazardous,
    'B' perspective,
    'O' twitter_option,
    'INDIA.'||servprov_xid servprov_gid,
    SUBSTR(tm,1,2) ||':'||SUBSTR(tm,3) origin_search_value,
    Location_xid destination_search_value,
    'INDIA' domain_name,
    'N' is_customer_rates_only
    BULK COLLECT INTO twitter_cols_t
    FROM
    (SELECT x.*,
    Q.twitter_gid
    FROM
    (SELECT 'INDIA.FS_'||H.servprov_xid||'_'||D.Location_xid||'_'||T.tm all_spec,
    servprov_xid ,
    tm ,
    Location_xid
    FROM
    (SELECT Location_xid
    FROM location
    WHERE location_xid IN ('1')
    AND domain_name ='INDIA'
    ) D,
    (SELECT servprov_xid
    FROM servprov
    WHERE(servprov_gid LIKE 'P_F%'
    AND SUBSTR(servprov_xid,2,1) IN ('2'))
    OR servprov_gid ='INDIA.FRESHMISC'
    ) H,
    (SELECT lpad(rownum-1,2,'0') ||'00' tm FROM sea WHERE rownum<25
    UNION
    SELECT lpad(rownum-1,2,'0') ||'30' tm FROM sea WHERE rownum<25
    ) T
    ) x,
    (SELECT * FROM twitter WHERE twitter_gid LIKE 'INDIA.FS%'
    ) Q
    WHERE x.all_spec=Q.twitter_gid(+)
    WHERE twitter_gid IS NULL;
    FORALL i in 1 .. twitter_cols_t.count
    --LOOP
    INSERT
    INTO twitter
    (twitter_gid ,
    twitter_xid ,
    origin_location_type ,
    destination_location_type,
    is_hazardous ,
    perspective ,
    twitter_option ,
    servprov_gid ,
    origin_search_value ,
    destination_search_value ,
    domain_name ,
    is_customer_rates_only)
    VALUES
    twitter_cols_t (i);
    --END LOOP;
    END f_t_s;
    Any idea where I am doing mistake
    Thanks in Advance,
    DIDI

    Hi,
    That was my typing mistake....
    This is correct code
    CREATE OR REPLACE PROCEDURE f_t_s (P_F IN VARCHAR2)
    IS
    TYPE twitter_cols_rt IS RECORD
    twitter_gid twitter.twitter_gid%TYPE,
    twitter_xid twitter.twitter_xid%TYPE,
    origin_location_type twitter.origin_location_type%TYPE,
    destination_location_type twitter.destination_location_type%TYPE,
    is_hazardous twitter.is_hazardous%TYPE,
    perspective twitter.perspective%TYPE,
    twitter_option twitter.twitter_option%TYPE,
    servprov_gid twitter.servprov_gid%TYPE,
    origin_search_value twitter.origin_search_value%TYPE,
    destination_search_value twitter.destination_search_value%TYPE,
    domain_name twitter.domain_name%TYPE,
    is_customer_rates_only twitter.is_customer_rates_only%TYPE
    TYPE twitter_cols_tt IS TABLE OF twitter_cols_rt INDEX BY PLS_INTEGER;
    twitter_cols_t twitter_cols_tt;
    BEGIN
    SELECT all_spec twitter_gid,
    SUBSTR(all_spec,7) twitter_xid,
    'location_code' origin_location_type,
    'location_code' destination_location_type,
    'N' is_hazardous,
    'B' perspective,
    'O' twitter_option,
    'INDIA.'||servprov_xid servprov_gid,
    SUBSTR(tm,1,2) ||':'||SUBSTR(tm,3) origin_search_value,
    Location_xid destination_search_value,
    'INDIA' domain_name,
    'N' is_customer_rates_only
    BULK COLLECT INTO twitter_cols_t
    FROM
    (SELECT x.*,
    Q.twitter_gid
    FROM
    (SELECT 'INDIA.FS_'||H.servprov_xid||'_'||D.Location_xid||'_'||T.tm all_spec,
    servprov_xid ,
    tm ,
    Location_xid
    FROM
    (SELECT Location_xid
    FROM location
    WHERE location_xid IN ('1')
    AND domain_name ='INDIA'
    ) D,
    (SELECT servprov_xid
    FROM servprov
    WHERE(servprov_gid LIKE 'P_F%'
    AND SUBSTR(servprov_xid,2,1) IN ('2'))
    OR servprov_gid ='INDIA.FRESHMISC'
    ) H,
    (SELECT lpad(rownum-1,2,'0') ||'00' tm FROM sea WHERE rownum<25
    UNION
    SELECT lpad(rownum-1,2,'0') ||'30' tm FROM sea WHERE rownum<25
    ) T
    ) x,
    (SELECT * FROM twitter WHERE twitter_gid LIKE 'INDIA.FS%'
    ) Q
    WHERE x.all_spec=Q.twitter_gid(+)
    WHERE twitter_gid IS NULL;
    FORALL i in 1 .. twitter_cols_t.count
    --LOOP
    INSERT
    INTO twitter
    (twitter_gid ,
    twitter_xid ,
    origin_location_type ,
    destination_location_type,
    is_hazardous ,
    perspective ,
    twitter_option ,
    servprov_gid ,
    origin_search_value ,
    destination_search_value ,
    domain_name ,
    is_customer_rates_only)
    VALUES
    twitter_cols_t (i);
    --END LOOP;
    END f_t_s;
    Thanks,
    DIDI

  • Deletion is taking long time using forall

    Hi,
           i am  inserting and deleting the rows using forall. insert taking less time to inset the rows but while coming to
    deletion it is taking more than 5 days long time to delete 18.5 million rows in a table using forall.
    the main table having 70 million rows.
    the code is..
       FETCH ref_typ  BULK COLLECT INTO l_id_tbl LIMIT 10000;
       begin
        FORALL i in  1..l_id_tbl.COUNT
           INSERT INTO   change_test (id,
                                 history,
                                 transaction,
                                 date)
                         VALUES (seq.nextval,
                                 'CHANGE_HIS',
                                 l_id_tbl(i),
                                 sysdate);
           exception
               when others then
                null;
        end;
        begin
            FoRALL i in 1..l_id_tbl.COUNT
              DELETE FROM change_his
                     where id = l_id_tbl(i);
           exception
               when others then
                 null;
       end;
      end loop;
    so  please give me a good solution  to delete the rows less than 5 days..

    Why are you wanting to do this using BULK COLLECT and FORALL?
    Why not just "insert ... select ..." and "delete ..."?
    Loading records into expensive PGA memory to insert them back on the database is bound to be slower (and use more server resources) than just doing a straight insert ... select ... statement.
    Explain exactly what you are trying to do.
    Re: 2. How do I ask a question on the forums?

  • JOB is created but SPOOL is not created - using SUBMIT stmt in WD

    Hi,
    I am submitting report from WD. PFB the code i used. This is cuccessfully creating the JOB in SM37 and the status is 'Finished'. But when I click for the SPOOL, it is giving me an error 'No list available'.
    I used the following code for submitting the program.
    * call the FM 'JOB_OPEN' and create the job.
      SUBMIT ztest TO SAP-SPOOL
        WITH pnppernr-low EQ pernr
        WITH pnpbukrs-low EQ bukrs
        SPOOL PARAMETERS lv_print_parameters
        WITHOUT SPOOL DYNPRO
        VIA JOB lv_name NUMBER lv_number " job name and number created from JOB_OPEN
        AND RETURN.
    * call the FM 'JOB_CLOSE' and close the job.
    The submit stmt is working perfectly fine when executed directly..from R/3. The spool is also being created.
    I tried debugging the same. This goes to the INITIALIZITION part of the program but no goin to START-OF-SELECTION.
    Pls suggest if I am missing something in the code.
    Thanks,
    Teja.

    >
    teja wrote:
    > Hi,
    >
    > I am submitting report from WD. PFB the code i used. This is cuccessfully creating the JOB in SM37 and the status is 'Finished'. But when I click for the SPOOL, it is giving me an error 'No list available'.
    >
    > I used the following code for submitting the program.
    >
    >
    > * call the FM 'JOB_OPEN' and create the job.
    >
    >   SUBMIT ztest TO SAP-SPOOL
    >     WITH pnppernr-low EQ pernr
    >     WITH pnpbukrs-low EQ bukrs
    >     SPOOL PARAMETERS lv_print_parameters
    >     WITHOUT SPOOL DYNPRO
    >     VIA JOB lv_name NUMBER lv_number " job name and number created from JOB_OPEN
    >     AND RETURN.
    >
    > * call the FM 'JOB_CLOSE' and close the job.
    >
    >
    > The submit stmt is working perfectly fine when executed directly..from R/3. The spool is also being created.
    >
    > I tried debugging the same. This goes to the INITIALIZITION part of the program but no goin to START-OF-SELECTION.
    >
    > Pls suggest if I am missing something in the code.
    >
    > Thanks,
    > Teja.
    Hi,
    I guess this wont work. Didnt you get any dump ?
    FM's with dialog screens,conversion exits would cause the webdynpro session to disconnect.

  • Problem in collect stmt

    hi all,
    I am doing report in which there is opening stock , closing stock and all movement wise stock.
    i am able to do all this for one material but when i am try for more than one material then value of last material is overwrite on other material.
    I m using collect stmt to do sum for all movement.
    plz help me.

    hi all,
    plz see my code look like this :
    TABLES : MSEG , MKPF , MAKT , MBEW.
    DATA : BEGIN OF ITAB OCCURS 0,
            LBKUM LIKE MSEG-LBKUM,
            LBKUM1 LIKE MSEG-LBKUM,
            MAKTX LIKE MAKT-MAKTX,
            LGORT LIKE MSEG-LGORT,
            BWART LIKE MSEG-BWART,
            ZEILE LIKE MSEG-ZEILE,
            MENGE LIKE MSEG-MENGE,
            MEINS LIKE MSEG-MEINS,
            MATNR LIKE MSEG-MATNR,
            WERKS LIKE MSEG-WERKS,
            SHKZG LIKE MSEG-SHKZG,
            MBLNR LIKE MKPF-MBLNR,
            BUDAT LIKE MKPF-BUDAT,
            SIGN(2),
            101_102 LIKE MSEG-MENGE,
    END OF ITAB.
    DATA : BEGIN OF ITAB_TOT OCCURS 0,
            MATNR LIKE MSEG-MATNR,
            LBKUM1 LIKE MSEG-LBKUM,
              TOTAL1 LIKE MSEG-MENGE,
            TOTAL1 TYPE P DECIMALS 3,
            CLO TYPE P DECIMALS 3,
            101_102 LIKE MSEG-MENGE,
    END OF ITAB_TOT.
    PARAMETERS : WERKS LIKE MSEG-WERKS DEFAULT 'BRHP' OBLIGATORY.
    SELECT-OPTIONS : MATNR FOR MSEG-MATNR OBLIGATORY.
    SELECT-OPTIONS: DAT  FOR MKPF-BUDAT.
    SELECT-OPTIONS: LGORT FOR MSEG-LGORT.
    START-OF-SELECTION.
      SELECT DISTINCT  MSEG~MATNR
             MSEG~LGORT
             MSEG~BWART
             MSEG~ZEILE
             MSEG~MENGE
             MSEG~MEINS
             MSEG~WERKS
            MSEG~LBKUM
             MSEG~SHKZG
             MKPF~MBLNR
             MKPF~BUDAT
             INTO CORRESPONDING FIELDS OF TABLE ITAB
             FROM MSEG
             INNER JOIN MKPF ON MSEG~MBLNR = MKPF~MBLNR
             WHERE MSEG~MATNR IN MATNR
            AND MSEG~LGORT IN LGORT
             AND MSEG~WERKS EQ WERKS
             AND mKPF~BUDAT IN DAT
             AND MSEG~ZEILE = 1
             order by mkpf~MBLNR.
    LOOP AT ITAB.
        IF ITAB-SHKZG = 'S'.
          ITAB-SIGN = '+'.
          MODIFY ITAB.
        ELSE.
          ITAB-SIGN = '-'.
          MODIFY ITAB.
        ENDIF.
      ENDLOOP.
    SORT ITAB BY MATNR.
    LOOP AT ITAB.
       IF ITAB-BWART = '121' OR ITAB-BWART = '122' .
          SELECT  MENGE INTO (ITAB-121_122) FROM MSEG  WHERE MATNR =
        ITAB-MATNR
          AND MBLNR = ITAB-MBLNR
          AND LGORT = ITAB-LGORT
          AND WERKS = ITAB-WERKS.
         AND ZEILE = ITAB-ZEILE.
            MODIFY ITAB.
          ENDSELECT.
        ENDIF.
         LOOP AT ITAB.
        IF ITAB-SHKZG = 'H'.
            ITAB-121_122 = ITAB-121_122 * -1.
            MODIFY ITAB.
        ELSE.
            ITAB-121_122 = ITAB-121_122.
            MODIFY ITAB.
         ENDIF.
         ENDLOOP.
      ENDLOOP.
    LOOP AT ITAB.
    SELECT LBKUM INTO (ITAB-LBKUM) FROM MSEG WHERE MATNR = ITAB-MATNR
    and
    MBLNR = ITAB-MBLNR AND WERKS = ITAB-WERKS AND ZEILE = 1.
    MODIFY ITAB.
    ENDSELECT.
    ENDLOOP.
    SORT ITAB BY  matnr mblnr.
    LOOP AT ITAB.
    IF ITAB[] IS NOT INITIAL.
    DELETE ADJACENT DUPLICATES FROM ITAB COMPARING MATNR .
    MOVE ITAB-lBKUM TO ITAB-LBKUM1.
    MODIFY ITAB.
    *APPEND ITAB_TOT1.
    ENDIF.
    ENDLOOP.
    LOOP AT ITAB .
      MOVE-CORRESPONDING ITAB TO ITAB_TOT.
      COLLECT ITAB_TOT.
    ENDLOOP.
    loop at itab_tot.
    write : / itab_tot-matnr , itab_tot-121_122 , itab-lbkum.
    endloop.
    i am not getting correct value of 121_122.
    what should i do?

  • Error While Executing FORALL

    Hello All,
    May i know why the following example from Oracle documentation is failing.
    CREATE TABLE coords (x NUMBER, y NUMBER);
    CREATE TYPE Pair AS OBJECT (m NUMBER, n NUMBER);
    DECLARE
       TYPE PairTab IS TABLE OF Pair;
       pairs PairTab := PairTab(Pair(1,2), Pair(3,4), Pair(5,6));
       TYPE NumTab IS TABLE OF NUMBER;
       nums NumTab := NumTab(1, 2, 3);
    BEGIN
       /* The following statement succeeds. */
       FORALL i in 1..3
          UPDATE coords SET (x, y) = (pairs(i).m, pairs(i).n)
             WHERE x = nums(i);
    END;
    Error:
    Error starting at line 37 in command:
    DECLARE
       TYPE PairTab IS TABLE OF Pair;
       pairs PairTab := PairTab(Pair(1,2), Pair(3,4), Pair(5,6));
       TYPE NumTab IS TABLE OF NUMBER;
       nums NumTab := NumTab(1, 2, 3);
    BEGIN
       /* The following statement succeeds. */
       FORALL i in 1..3
          UPDATE coords SET (x, y) = (pairs(i).m, pairs(i).n)
             WHERE x = nums(i);
    END;
    Error report:
    ORA-06550: line 9, column 34:
    PL/SQL: ORA-01767: UPDATE ... SET expression must be a subquery
    ORA-06550: line 9, column 7:
    PL/SQL: SQL Statement ignored
    06550. 00000 -  "line %s, column %s:\n%s"
    *Cause:    Usually a PL/SQL compilation error.
    *Action:
    Thank you.

    Based on your advise i did the below example,
    DECLARE
       TYPE PairTab IS TABLE OF Pair;
       pairs PairTab := PairTab(Pair(1,2), Pair(3,4), Pair(5,6),Pair(7,8),Pair(9,10));
       TYPE NumTab IS TABLE OF NUMBER;
       nums NumTab := NumTab(1,2,3,4,5);
       vnum1 NUMBER;
       vnum2 number;
    BEGIN
       FORALL i IN 1 .. 5
       UPDATE coords
       SET   (x, y) = (SELECT pairs(i).m, pairs(i).n
                       FROM dual)
       WHERE  x = nums(i);
    END;
    INSERT INTO coords VALUES(1,10);
    INSERT INTO coords VALUES(2,10);
    insert into coords values(3,10);
    INSERT INTO coords VALUES(4,10);
    INSERT INTO coords VALUES(5,10);
    commit;
    After insertng the data into coords table i execute the above plsql block i got the below output.I wonder how come rows 2,3 & 5 are updated with 9,10.
    Output:
    1
    2
    9
    10
    9
    10
    7
    8
    9
    10

  • ***** in the output AT END stmt

    I am getting ***** in the output, if I use the at end stmt. Can anybody tell me the reason and teh solution??

    Hello,
    When using AT END ENDAT all fields to the right of the current control key(Matnr in your case) will be filled with ****s.  This means that you can do things like SUM on an amount or quantity field.  If you need some of the character type fields at the  AT END you will have to code around that.
    eg (please note this is not syntactically accurate or complete code)
    data ls_tmp like ls_itab.
    loop at it_itab into ls_itab.
       ls_tmp = ls_itab.       " save current line of itab
       at end matnr
        do something ie sum or whatever your requirements are
          write ls_tmp-charfield.
       endat.
    endloop.
    Regards
    Greg Kern

  • Error While Using FORALL --

    Hi All,
    I am using FORALL for inserting 40000 records from the file to the table. After reading data from the file it has been stored in type Table array, But while executing FORALL statement its giving ora-00600. error.
    It is a memory error, some where I read to using LIMIT in fetch. But I am not using any fetch or Cursor. Can any body Help.
    SKM
    =================== ================= Package Code
    create or replace package insertpackage as
         TYPE tabSNO IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;
         TYPE tabSNO1 IS TABLE OF VARCHAR2(1) INDEX BY BINARY_INTEGER;
         TYPE tabSDATE IS TABLE OF VARCHAR2(20) INDEX BY BINARY_INTEGER;
         TYPE SNO IS TABLE OF NUMBER(5) INDEX BY BINARY_INTEGER;
    procedure insertpro(snoArray IN SNO, sDate IN tabSDATE, sArray IN tabSNO, sArray1 IN tabSNO1);
    end insertpackage;
    create or replace package body insertpackage as
         procedure insertpro(snoArray IN SNO, sDate IN tabSDATE, sArray IN tabSNO, sArray1 IN tabSNO1) is
         begin
              forall i in 1..sArray.last
                   insert into test(s_no, s_date, s_co, s_type)
                   values(snoArray(i), TO_DATE(sDate(i),'YYYY-MM-DD HH24.MI.SS'), sArray(i), sArray1(i));
         end;
    end insertpackage;
    /

    Hi User,
    The error
    implementation restriction: cannot reference fields of BULK In-BIND table of recordsis because bulk bind cannot use table of composite types.
    Please See the below,
    http://dba-blog.blogspot.com/2005/08/using-of-bulk-collect-and-forall-for.html
    And rewrite your code like this,
    DECLARE
       CURSOR EMP_CUR
       IS
          SELECT EMPNO, ENAME
            FROM EMP;
       TYPE TAB_EMP_EMPNO IS TABLE OF EMP.EMPNO%TYPE;
       V_TAB_EMPNO   TAB_EMP_EMPNO;
       TYPE TAB_EMP_ENAME IS TABLE OF EMP.ENAME%TYPE;
       V_TAB_ENAME   TAB_EMP_ENAME;
    BEGIN
       OPEN EMP_CUR;
       FETCH EMP_CUR BULK COLLECT INTO V_TAB_EMPNO, V_TAB_ENAME;
       FORALL I IN V_TAB_EMPNO.FIRST .. V_TAB_EMPNO.LAST
          INSERT INTO EMP_TEMP
                      (EMPNO, ENAME
               VALUES (V_TAB_EMPNO (I), V_TAB_ENAME (I)
       CLOSE EMP_CUR;
    END;Thanks,
    Shankar

  • Using Sequence in FORALL Statement

    I'm using a package to get the nextval in a sequence object. Basically, it is a function that returns select user_seq.nextval from dual.
    But I get 'column not allowed here' error. PL/SQL: ORA-00984: column not allowed here
    OPEN users_ins ;
                 LOOP
                    FETCH         naf_users_ins
                    BULK COLLECT
                    INTO           arr_person_key
                                 , arr_person_id
                                 , arr_first_name
                                 , arr_middle_name
                                 , arr_last_name
                                 , arr_username
                                 , arr_user_status_seq
                                 , arr_creation_date
                                 , arr_comments
                   LIMIT         100 ;
    FORALL idx IN 1 ..  arr_person_key.COUNT
                     SAVE EXCEPTIONS
                       INSERT INTO users
                        (   user_seq
                          , person_key
                          , person_id
                          , first_name
                          , middle_name
                          , last_name
                          , username
                          , user_status_seq
                          , creation_date
                          , comments
                        VALUES  (   *pkg_admin.get_nextval*
                                  , arr_person_key(idx)
                                  , arr_person_id(idx)
                                  , arr_first_name(idx)
                                  , arr_middle_name(idx)
                                  , arr_last_name(idx)
                                  , arr_username(idx)
                                  , arr_user_status_seq(idx)
                                  , arr_creation_date(idx)
                                  , arr_comments(idx)
    EXIT WHEN users_ins%NOTFOUND ;
                 END LOOP ;
                 CLOSE users_ins;
    c/code]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

    Hi,
    I've recently completed a similar task, but I declared a collection with the rowtype of the table. I also added the sequence in the query of my cursor. Take a look at the following example.
    CREATE OR REPLACE PROCEDURE Insert_OR_ExternalService
    IS
    TYPE externalService_tbl IS TABLE OF OR_ExternalService%ROWTYPE;
    externalService externalService_tbl;
    CURSOR OR_ExternalServiceCursor
    IS
    select
    SEQ_ID.NEXTVAL as "Id",
    column as "ExternalId",
    column as "ExternalSystem",
    from table1
    where ...;
    BEGIN
    OPEN OR_ExternalServiceCursor;
    LOOP
    FETCH OR_ExternalServiceCursor BULK COLLECT INTO externalService LIMIT 1000;
    FORALL i IN 1 .. externalService.count
    INSERT INTO OR_ExternalService values externalService(i);
    COMMIT;
    EXIT WHEN OR_ExternalServiceCursor%NOTFOUND;
    END LOOP;
    CLOSE OR_ExternalServiceCursor;
    END;

  • PLS-00435: DML statement without BULK In-BIND cannot be used inside FORALL

    See code below: Have googled the error but not sure how to fix the code. ANy help would be most greatful.
    DECLARE
    CURSOR c1
    IS
    SELECT /*+ parallel(tr,8)*/ DISTINCT tr.ACC ACC, tr.MET_ID METID, to_char(max(TRUNC(PKG_LSR_IMPOSITION.convertXXMMDDToDate(tr.DATETR0))),'YYYY') dt
    FROM CTTR0FIL_CDC tr
    JOIN transaction_action_sd sd on (sd.TRANSACTION_CODE = tr.RESULT)
    WHERE sd.ACTION_TYPE = 'PAYMENT'
    and to_char(TRUNC(PKG_LSR_IMPOSITION.convertXXMMDDToDate(tr.DATETR0)),'YYYY') = '1987'
    GROUP BY tr.ACC, tr.MET_ID, to_char(TRUNC(PKG_LSR_IMPOSITION.convertXXMMDDToDate(tr.DATETR0)),'YYYY');
    SUBTYPE PAY_DATES IS c1%ROWTYPE;
    TYPE TMP_TABLE IS TABLE OF PAY_DATES INDEX BY PLS_INTEGER;
    TBROWS TMP_TABLE;
    temp VARCHAR2(100);
    Begin
    DBMS_OUTPUT.ENABLE(10000);
    OPEN c1;
    LOOP
    FETCH c1 BULK COLLECT INTO TBROWS LIMIT 1000;
    FORALL i IN 1..TBROWS.COUNT
    SELECT /*+ parallel(da,8)*/ da.ACC INTO temp
              FROM CTDA0FIL_CDC da
    WHERE da.ACC = TBROWS(i).ACC AND da.MET_ID = TBROWS(i).MET_ID AND da.ACC = '07000006P' AND da.MET_ID = 4;
         DBMS_OUTPUT.PUT_LINE('inside');
    EXIT WHEN c1%notfound;
    END LOOP;
    CLOSE c1;
    END;
    Thanks
    Simon

    I tried using a normal for loop instead of a forall loop (see code below). But this came up the error also see below. Or can I not use selects in this way???
    OPEN c1;
    LOOP
    FETCH c1 BULK COLLECT INTO tbrows LIMIT 1000;
    FOR i IN TBROWS.FIRST .. TBROWS.LAST
         LOOP
              SELECT /*+ parallel(da,8)*/ da.ACC INTO temp
              FROM CTDA0FIL_CDC da WHERE da.ACC = TBROWS(i).ACC AND da.MET_ID = TBROWS(i).MET_ID AND da.ACC = '07000006P' AND da.MET_ID = 4;
         DBMS_OUTPUT.PUT_LINE('inside');
    EXIT WHEN c1%notfound;
    END LOOP;
    END LOOP;
    CLOSE c1;
    END;
    Error:
    DECLARE
    ERROR at line 1:
    ORA-06502: PL/SQL: numeric or value error
    ORA-06512: at line 24

  • Use of Select stmts with Update stmts

    Hi,
    I want to execute the following update stmt...
    UPDATE Test1_tab a
    SET a.invpln_seq_no = (SELECT b.seq_no
    FROM Test2_tab b
    WHERE b.contract_id = a.contract_id
    AND b.date_from = a.period_from_date)
    WHERE a.invpln_seq_no != (SELECT b.seq_no
    FROM Test2_tab b
    WHERE b.contract_id = a.contract_id
    AND b.date_from = a.period_from_date)
    Here the problem is I have used 'SELECT b.seq_no FROM Test2_tab b WHERE b.contract_id = a.contract_id AND b.date_from = a.period_from_date' twice, one in the SET clause and the other one in WHERE clause...But it is the same SELECT stmt...So this same Select stmt runs twice when I run the whole update stmt I guess. Is there a way to do the above update, where it runs the SELECT stmt only once...
    Any input is highly appreciated...
    Thanks And Best Regards,
    /Dinesh...

    Then you can use Merge statement instead.
    try this
    merge into test1_tab t1
    using
    (SELECT a.rowid,b.seq_no SEQ_DEST
    FROM test1_tab a,test2_tab b
    WHERE b.contract_id = a.contract_id
    AND  b.date_from = a.period_from_date
    AND a.invpln_seq_no != b.seq_no) t2
    ON (t1.rowid=t2.rowid)
    WHEN MATCHED THEN
    UPDATE SET t1.invpln_seq_no=t2.seq_destor if you are sure that sno is a unique key with out any duplicates and if you are going to perform one time manual update then you can use an undocumented hint /*+ bypass_ujvc */ to do this.
    *DO NOT include this code if you are about to add it in a production procedure or a function
    UPDATE /*+ bypass_ujvc */ (SELECT a.invpln_seq_no SEQ_SRC,b.seq_no SEQ_DEST FROM test1_tab a,test2_tab  b
    WHERE b.contract_id = a.contract_id
    AND  b.date_from = a.period_from_date
    AND a.invpln_seq_no != b.seq_no)
    SET SEQ_SRC = SEQ_DESTRegards,
    Prazy

  • FORALL MERGE statement works in local database but not over database link

    Given "list", a collection of NUMBER's, the following FORALL ... MERGE statement should copy the appropriate data if the record specified by the list exists on both databases.
    forall i in 1..list.count
    merge into tbl@remote t
    using (select * from tbl
    where id = list(i)) s
    on (s.id = t.id)
    when matched then
    update set
    t.status = s.status
    when not matched then
    insert (id, status)
    values (s.id, s.status);
    But this does not work. No exceptions, but target table's record is unchanged and "sql%rowcount" is 0.
    If the target table is in the local database, the exact same statement works:
    forall i in 1..list.count
    merge into tbl2 t
    using (select * from tbl
    where id = list(i)) s
    on (s.id = t.id)
    when matched then
    update set
    t.status = s.status
    when not matched then
    insert (id, status)
    values (s.id, s.status);
    Does anyone have a clue why this may be a problem?
    Both databases are on Oracle 10g.
    Edited by: user652538 on 2009. 6. 12 오전 11:29
    Edited by: user652538 on 2009. 6. 12 오전 11:31
    Edited by: user652538 on 2009. 6. 12 오전 11:45

    Should throw an error in my opinion. The underlying reason for not working is basically because of
    SQL> merge into   t@remote t1
         using   (    select   sys.odcinumberlist (1) from dual) t2
            on   (1 = 1)
    when matched
    then
       update set i = 1
    Error at line 4
    ORA-22804: remote operations not permitted on object tables or user-defined type columnsSame reason as e.g.
    insert into t@remote select * from table(sys.odcinumberlist(1,2,3))doesn't work.

Maybe you are looking for