Home » SQL & PL/SQL » SQL & PL/SQL » Bulk insert and record missing
Bulk insert and record missing [message #613594] Thu, 08 May 2014 06:56 Go to next message
Malakay79
Messages: 41
Registered: September 2007
Member
Hi,
I need to insert some records from a table to another.
I use bulk and it's fast but Oracle do not insert last 8000 record.
this is the code

DECLARE
    CURSOR nuovi
    IS
        SELECT di
        FROM tab_new;

    TYPE nuovi_aat IS TABLE OF tab_new%ROWTYPE
        INDEX BY PLS_INTEGER;

    l_nuovi nuovi_aat;
BEGIN
    OPEN nuovi;
    LOOP
        FETCH nuovi
            BULK COLLECT INTO l_nuovi LIMIT 10000;
  EXIT WHEN nuovi%notfound;

        FORALL i IN 1 .. l_nuovi.count
       -- FOR indx IN nuovi.first .. nuovi.last


             INSERT INTO tab /*+ APPEND */
                  (
                     ...
                  )
         SELECT col1,col2....
           FROM user.tables
          WHERE col_id IN (l_nuovi(i).id);


        COMMIT;

   END LOOP;

   CLOSE nuovi;
 END;


Can anyone tell me why?
Re: Bulk insert and record missing [message #613595 is a reply to message #613594] Thu, 08 May 2014 07:04 Go to previous messageGo to next message
Michel Cadot
Messages: 68647
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Why don't use a single INSERT SELECT statement which faster than any BULK COLLECT.

Apart from that, when you use BULK COLLECT EXIT should just before END LOOP and not just after FETCH.

In the end, do NOT commit inside a cursor loop, in addition to be out of SQL standard it is a good way to get ORA-01555 errors.

Re: Bulk insert and record missing [message #613596 is a reply to message #613594] Thu, 08 May 2014 07:04 Go to previous messageGo to next message
Littlefoot
Messages: 21808
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
Why do you need PL/SQL? Simple
insert into tab ...
select col1, col2, ...
from user_tables
where col_id in (select di from tab_new)
would suffice.
Re: Bulk insert and record missing [message #613598 is a reply to message #613596] Thu, 08 May 2014 07:18 Go to previous messageGo to next message
DrabJay
Messages: 32
Registered: May 2013
Member
When Bulk Collecting with a Limit clause if the number of records returned is less than the limit then nuovi%NOTFOUND evaluates to True and the loop exits. You either need to move this check to the end of the loop or change the check to one such as:
EXIT WHEN l_nuovi.COUNT = 0;
Re: Bulk insert and record missing [message #613600 is a reply to message #613598] Thu, 08 May 2014 07:25 Go to previous messageGo to next message
Malakay79
Messages: 41
Registered: September 2007
Member
Thank you.

Sometimes I need to insert 300000/400000 record.

The classic insert is slower.
Re: Bulk insert and record missing [message #613601 is a reply to message #613594] Thu, 08 May 2014 07:37 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
As others alrady noticed, plain insert would do. Now about your issue. You misunderstand cursor attribute %notfound. It doesn't mean no more rows were found. It means number of rows requested to fetch was not found. When you do regular single row fetch both statements are same, but you fetch 10000 rows at a time. As a result your code will exit when last fetch fetched from 0 to 9999 rows thus potetially losing that last batch. Change:

EXIT WHEN nuovi%notfound;


to:

EXIT WHEN l_nuovi.count = 0;


SY.

Re: Bulk insert and record missing [message #613604 is a reply to message #613600] Thu, 08 May 2014 08:08 Go to previous message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Malakay79 wrote on Thu, 08 May 2014 17:55
The classic insert is slower.


Eh? Simple insert should be faster than doing it in PL/SQL. If you say so, then show it. We need proof, just don't say it.

By the way, there are saveral ways to improve it. Such as /*+ append */ hint, which eliminates the undo operation(but only for balance tree indexes). nologging option can also improve the performance since it eliminates the redo operation.
Previous Topic: Performance of Window Sort
Next Topic: 1 Statement Runs other Doesn't
Goto Forum:
  


Current Time: Fri Apr 26 15:45:36 CDT 2024