Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Processing within the FORALL Loop

Posted on 2013-05-10
8
396 Views
Last Modified: 2013-05-15
Can I perform logic inside of a forall loop?
What I would like to do is increment a record id each time a row of data is inserted.

CREATE OR REPLACE PROCEDURE fast_proc (p_param IN VARCHAR2)
 IS

 TYPE ARRAY IS TABLE OF T1%ROWTYPE;
 l_data ARRAY;
 max_rec NUMBER;

 CURSOR c IS
 SELECT *
 FROM test_table t1
 inner join test_table_2 t2
 on t2.col1 = t1.col1;

 BEGIN
     max_rec := getMaxRecNumber; -- from function
     OPEN c;
     LOOP
     FETCH c BULK COLLECT INTO l_data LIMIT 100;
     
     FORALL i IN 1..l_data.COUNT
     
      -- Need to increment record number each time inserted
     
     -- Add max_rec
     max_rec  := max_rec + 1;

     INSERT INTO t1 VALUES l_data(i);

     EXIT WHEN c%NOTFOUND;
     END LOOP;
     CLOSE c;
 END fast_proc;
 /
0
Comment
Question by:cookiejar
8 Comments
 
LVL 35

Expert Comment

by:YZlat
ID: 39156346
are you getting any erros?
0
 
LVL 77

Expert Comment

by:slightwv (䄆 Netminder)
ID: 39156441
I believe you can only perform a single DML statement in a FORALL.

I don't understand the need to increment maxvalue.  Would it not end up the same as getMaxRecNumber + l_data.COUNT?
0
 
LVL 77

Accepted Solution

by:
slightwv (䄆 Netminder) earned 500 total points
ID: 39156455
I also don't understand why you want to create in in-memory table and insert loop.

Why not just do it as a single insert?

INSERT INTO some_table
SELECT *
 FROM test_table t1
 inner join test_table_2 t2
 on t2.col1 = t1.col1;
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 29

Expert Comment

by:MikeOM_DBA
ID: 39156462
Did you try this?:
 . . .
FORALL i IN 1..l_data.COUNT
     INSERT INTO t1 VALUES l_data(i);

     -- Add max_rec
     max_rec  := max_rec + l_data.COUNT;

Open in new window

:p
0
 
LVL 35

Expert Comment

by:Mark Geerlings
ID: 39156509
"Can I perform logic inside of a forall loop?"
Maybe.  But, do you even need to?

I agree with slightwv.  If you really want a "fast_proc" don't use a PL\SQL loop.  Just do a SQL insert based on a select, and use SQL%ROWCOUNT to get the number of records processed, like this:

CREATE OR REPLACE PROCEDURE fast_proc IS

 max_rec NUMBER;

 BEGIN
     max_rec := getMaxRecNumber; -- from function

     INSERT INTO t1
     SELECT *
     FROM test_table t1
     inner join test_table_2 t2
     on t2.col1 = t1.col1;
      
     max_rec  := max_rec + SQL%ROWCOUNT;

 END fast_proc;
 /

Note: the code you posted here did not use the input parameter at all, so I left it out.
0
 

Author Comment

by:cookiejar
ID: 39157166
I also don't understand why you want to create in in-memory table and insert loop.

So doing the following will be more efficient?

INSERT INTO t1
     SELECT *
     FROM test_table t1
     inner join test_table_2 t2
     on t2.col1 = t1.col1;
       
     max_rec  := max_rec + SQL%ROWCOUNT
0
 
LVL 77

Expert Comment

by:slightwv (䄆 Netminder)
ID: 39157399
>>So doing the following will be more efficient?

Set up a quick test and try both methods.

Think about it.

Your way:
Create a cursor.
Load the entire result set into memory in a PL/SQL table.
Loop through it and insert the rows into another table.

or

Have the database create an implicit cursor and insert directly.

Which seems best?

Faster yet, use an APPEND hint on the insert.  Before you just make the jump to that you need to understand what that is doing.
0
 
LVL 48

Expert Comment

by:PortletPaul
ID: 39157635
>>So doing the following will be more efficient?
yes, absolutely

a: "set operations" performed by internal dbms facilities -v- b: procedural code you build

a: will win
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
PL/SQL Two changes 7 34
Problem with duplicate records in Oracle query 16 40
Sybase and replication server 13 39
subtr returning incorrect value 8 31
Background In several of the companies I have worked for, I noticed that corporate reporting is off loaded from the production database and done mainly on a clone database which needs to be kept up to date daily by various means, be it a logical…
Using SQL Scripts we can save all the SQL queries as files that we use very frequently on our database later point of time. This is one of the feature present under SQL Workshop in Oracle Application Express.
This video shows how to Export data from an Oracle database using the Datapump Export Utility.  The corresponding Datapump Import utility is also discussed and demonstrated.
This video shows how to copy an entire tablespace from one database to another database using Transportable Tablespace functionality.

838 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question