批量收集并通过动态查询实现永久保存

时间:2019-02-12 06:56:11

标签: plsql

Declare
    Vquery varchar2(32000);
    Vitem varchar2(50);
    Vskuloc varchar2(50);
    vstartdate Date;
    Vdur Number;
    vtype Number;
    vqty Float(126);
    GP_ohpost Date:= fnc_ohpost;
    sdate1 Date:= to_date('01/01/1970','dd/mm/yyyy');

    Cursor C_DRIVER is
        (Select h.*,b.item,b.skuloc,h.rowid
         FROM SCPOMGR.histwide h, SCPOMGR.dfutosku b
         WHERE  h.dmdunit=b.dmdunit
         AND  h.loc=b.dfuloc
         AND (b.eff = Sdate1 OR b.eff <= h.startdate
         AND b.disc = Sdate1 OR b.disc > h.startdate)
         And NOT EXISTS (SELECT 1 FROM SCPOMGR.SKUHIST d
                 WHERE b.dmdunit = d.item
                 AND   b.skuloc =  d.loc
                 AND   h.startdate = d.startdate
        )) order by h.StartDate;
    TYPE GP_cursor_Type IS TABLE OF C_DRIVER%ROWTYPE;
    GP_cursor_tab GP_cursor_Type := GP_cursor_type();
    c_limit constant PLS_INTEGER DEFAULT 10;
    TYPE GP_Insert_type IS TABLE OF scpomgr.skuhist%ROWTYPE; 
    GP_Insert_tab GP_Insert_type := GP_Insert_type(); 
    GP_tot_accept_fetched NUMBER := 0;
begin    
    OPEN C_DRIVER;
    LOOP
        FETCH c_driver BULK COLLECT INTO GP_cursor_tab limit c_limit;
        Exit when c_driver%NOTFOUND;
        FOR i IN GP_cursor_tab.FIRST .. GP_cursor_tab.LAST LOOP
        vquery:= 'Select ...<skipped to make post shortest>';
        Execute immediate vquery BULK COLLECT INTO GP_Insert_tab;
        FORALL i IN INDICES OF GP_Insert_tab
            Insert into scpomgr.skuhist 
             values( GP_Insert_tab(i).startdate
                              ,1
                              ,10080
                              ,GP_Insert_tab(i).qty
                              ,GP_Insert_tab(i).item
                              ,GP_Insert_tab(i).loc
        );
        End Loop;
    End Loop;       
    Close C_DRIVER;
END; 
/

我想在这里做的是我想在循环外使用forall查询,但是如果我在循环外使用forall和第二个数组,那么所有记录都不会插入到最终表中。 。请给我建议一些解决方案....

1 个答案:

答案 0 :(得分:1)

安吉塔。
我不知道您的表的结构,因此我制作了一个简单的表以了解此处应使用的内容:

create table histwide (f1 number);
insert into histwide values (1);
insert into histwide values (2);

create table skuhist (f1 number);

select * from histwide
select * from skuhist

现在,我更改了您的代码,并在注释中保留了更改的代码。似乎有效。我认为麻烦是因为在循环开始时Exit when c_driver%NOTFOUND;被使用了。 FORALL是错误的,因为在第一次获取游标之后,游标为空(如果达到限制)。
因此,我为您解决的情况:

Declare
    Vquery varchar2(32000);
    Vitem varchar2(50);
    Vskuloc varchar2(50);
    vstartdate Date;
    Vdur Number;
    vtype Number;
    vqty Float(126);
    GP_ohpost Date:= trunc(sysdate); --fnc_ohpost;
    sdate1 Date:= to_date('01/01/1970','dd/mm/yyyy');

    Cursor C_DRIVER is
                        (Select h.*--,b.item,b.skuloc,h.rowid
                                    --FROM SCPOMGR.histwide h, SCPOMGR.dfutosku b
                           FROM histwide h
                                    /*WHERE  h.dmdunit=b.dmdunit
                                                AND  h.loc=b.dfuloc
                                                AND (b.eff = Sdate1 OR b.eff <= h.startdate
                                                AND b.disc = Sdate1 OR b.disc > h.startdate)
                                    And NOT EXISTS (SELECT 1 FROM SCPOMGR.SKUHIST d
                                    WHERE b.dmdunit = d.item
                                    AND   b.skuloc =  d.loc
                                    AND   h.startdate = d.startdate
                                    )) order by h.StartDate*/
                           );
    TYPE GP_cursor_Type IS TABLE OF C_DRIVER%ROWTYPE;
    GP_cursor_tab GP_cursor_Type := GP_cursor_type();
    c_limit constant PLS_INTEGER DEFAULT 10;
    TYPE GP_Insert_type IS TABLE OF skuhist%ROWTYPE; --scpomgr.skuhist%ROWTYPE; 
    GP_Insert_tab GP_Insert_type := GP_Insert_type(); 
    GP_tot_accept_fetched NUMBER := 0;
begin
    OPEN C_DRIVER;
    LOOP
        FETCH c_driver BULK COLLECT INTO GP_cursor_tab limit c_limit;


        Exit when GP_cursor_tab.count = 0;
      dbms_output.put_line('arr cur size: '||GP_cursor_tab.count);

        FOR i IN GP_cursor_tab.FIRST .. GP_cursor_tab.LAST LOOP

            vquery:= 'Select * from histwide';
            Execute immediate vquery BULK COLLECT INTO GP_Insert_tab;
         dbms_output.put_line('arr size: '||GP_Insert_tab.count);

--          FORALL j IN INDICES OF GP_Insert_tab
                FORALL j in GP_Insert_tab.first..GP_Insert_tab.last --works too
                Insert into skuhist --scpomgr.skuhist 
                values(GP_Insert_tab(j).f1
                         /*GP_Insert_tab(i).startdate
                        ,1
                        ,10080
                        ,GP_Insert_tab(i).qty
                        ,GP_Insert_tab(i).item
                        ,GP_Insert_tab(i).loc*/
                        );
        End Loop;

        Exit when c_driver%NOTFOUND; --it should be at end of the loop.

    End Loop;
    Close C_DRIVER;
END; 
/

希望对您有帮助