简体   繁体   中英

Bulk insert with forall syntax using PL/SQL

I'm used to work with T-SQL, but currently I'm working on a project with PL/SQL, so syntax is a bit different at times.

Right now, I'm trying to insert around 5000 records in the database. This will happen through 12 different connections. (I have 12 XML different XML files which I read and I want to insert all the data for each XML in the corresponding table)

My first idea was to generate a new INSERT INTO query for every insert, but I'm guessing this is gonna give some real performance issues.

Next I've read about INSERT ALL INTO <table_name> , but I'm not sure of this will even solve the performance issue?

Lastly, I've read that the FORALL would dramatically increase the speed when doing a bulk INSERT. ( http://www.dba-oracle.com/oracle_news/news_plsql_forall_performance_insert.htm )
Unfortunately, since my PLSQL knowledge isn't that great yet, I have no idea how to pull this off.

I want to do something in the lines of:

FORALL i IN 1..10
    INSERT INTO DELETEME (ID, NAME) VALUES (i, 'name' + i);

This is my table structure:

ID      NUMBER(10,0)
NAME    VARCHAR2(255 BYTE)

This is what I'm getting:

Error starting at line : 2 in command -
        INSERT INTO DELETEME (ID, NAME) VALUES (i, 'name' + i)
Error at Command Line : 2 Column : 61
Error report -
SQL Error: ORA-00984: column not allowed here
00984. 00000 -  "column not allowed here"
*Cause:    
*Action:

What would be easiest way to bulk insert using FORALL? Or do you guys know any good alternatives?

You have several errors in your code. One is a simply syntax error, try

... VALUES (i, 'name' || i);

In Oracle strings are concatenated by || not by + (nor & )

Apart from that FORALL is used for PL/SQL Tables. You can run it like this

DECLARE
    TYPE nameTable IS TABLE OF INTEGER;
    names nameTable;
BEGIN   
    names := nameTable(10,20,30,40);
    FORALL i IN INDICES OF names
       INSERT INTO DELETEME (ID, NAME) VALUES (names(i), 'name' ||names(i) );   
END;

In case you need just a simple sequence you can also run

INSERT INTO DELETEME (ID, NAME)
SELECT LEVEL, 'name' || LEVEL
FROM dual
CONNECT BY LEVEL <= 10;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM