Regarding Bulk Collect Operations
I would like to know what things need to be considered in order to implement the bulk collect operations. I have tables with >100,000 rows, for which I am planning to use Bulk collect. Am I correct in saying that bulk collect is a memory intensive operation.
Any help would be appreciated.
Thanks
You will want to use the LIMIT clause to only bulk collect up to 1000 rows or so at a time.
http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:5918938803188
Similar Messages
-
I need an help regarding Bulk collect
Can we use bulkcollect with sys_refursor ?
for ex :
create or replace procedure sampelpro ( recs out sys_refcursor) is
begin
execute immediate 'select * from table1' bulk collect into recs ;
end sampelpro;
Note : table1 has 1+ laks record
if the above code is not possible then let me know any possible ways ?Hi and welcome to the forum
Can we use bulkcollect with sys_refursor ?No, and you shouldn't.
Your signature says that OUT parameter is a cursor. A cursor is not a resultset, but rather a pointer to one.
So your best choice is probably just to use that, and not try to select into a collection.
Note : table1 has 1+ laks recordEven more important then not to return a collection, but a cursor. (Although I don't remember what a lak is)
Example on how to use:
create or replace procedure sampelpro (recs out sys_refcursor)
is
begin
open recs for 'select empno, ename from emp';
end sampelpro;
Procedure er oprettetAnd a test. Imagine this being a Java client or something the like
SQL> var c refcursor
SQL> exec sampelpro(:c)
PL/SQL-procedure er udf°rt.
SQL> print c
EMPNO ENAME
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
EMPNO ENAME
7900 JAMES
7902 FORD
7934 MILLER
14 rµkker er valgt.
SQL>Blushadow has a nice post on cursors here:
PL/SQL 101 : Understanding Ref Cursors
Regards
Peter -
Hi,
I have some problem in BULK binding.
See below code, we have three columns in pl/sql record and table based on that record is populated with rows.
Now requirement is like, I want to store two of the columns in table with the help of FORALL statement.
So tried with below code. But it is not working.
How we can achieve this with the help of forall statement.
Please comment...
declare
type p_ref is ref cursor;
ref1 p_ref;
type p_rec is record
(owner varchar2(100),
table_name varchar2(100),
tablespace_name varchar2(100));
type p_tab is table of p_rec;
tab1 p_tab;
begin
open ref1 for 'select 123,table_name,tablespace_name from user_tables where rownum<=10';
fetch ref1 bulk collect into tab1;
close ref1;
forall i in tab1.first..tab1.last
insert into test_tab1(table_name,tablespace_name)
values(tab1(i).table_name,tab1(i).tablespace_name);
end;
ERROR at line 19:
ORA-06550: line 19, column 8:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND
table of records
ORA-06550: line 19, column 8:
PLS-00382: expression is of wrong type
ORA-06550: line 19, column 27:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND
table of records
ORA-06550: line 19, column 27:
PLS-00382: expression is of wrong type
ORA-06550: line 19, column 8:
PL/SQL: ORA-22806: not an object or REF
ORA-06550: line 18, column 1:
PL/SQL: SQL Statement ignoredSee below code, I do want to share one pl/sql for both table(test_tab1,test_tab) insertion.
SQL> desc test_tab1
Name Null? Type
TABLE_NAME NOT NULL VARCHAR2(30)
TABLESPACE_NAME VARCHAR2(30)
SQL> desc test_tab
Name Null? Type
OWNER NOT NULL VARCHAR2(30)
TABLE_NAME NOT NULL VARCHAR2(30)
TABLESPACE_NAME VARCHAR2(30)
declare
type p_ref is ref cursor;
ref1 p_ref;
type p_rec is record
(owner varchar2(100),
table_name varchar2(100),
tablespace_name varchar2(100));
type p_tab is table of p_rec;
tab1 p_tab;
opt number := &opt;
begin
IF opt =1 THEN
open ref1 for 'select 123,table_name,tablespace_name from user_tables where rownum<=10';
ELSE
open ref1 for 'select owner,table_name,tablespace_name from all_tables where rownum<=10';
END IF;
fetch ref1 bulk collect into tab1;
close ref1;
forall i in tab1.first..tab1.last
IF opt=1 THEN
insert into test_tab1(table_name,tablespace_name)
values(tab1(i).table_name,tab1(i).tablespace_name);
ELSE
insert into test_tab values(tab1(i));
END IF;
end; -
Bulk collect in pl/sql table SOLVED
Hi All,
TYPE r_nparameter IS RECORD( col1 tab.col1%TYPE, col2 tab.col2%TYPE);
TYPE t_no_seq IS TABLE OF r_nparameter INDEX BY BINARY_INTEGER;
the t_no_seq is not initialized.
My Question is
If we use t_itn_seq, in a BULK COLLECT operation in a select statement as...
SELECT col1, col2 BULK COLLECT INTO t_no_seq
and there is no record found for this query and exception is taken care of....thereafter we use this table in for loop as..
FOR icount IN 1..t_no_seq.COUNT
will this count raise any exception?
Best Regards.
Message was edited by:
user560602It's not difficult to test this yourself...
SQL> declare
2 type t_x is table of number index by binary_integer;
3 v_x t_x;
4 begin
5 select rownum
6 bulk collect into v_x
7 from dual
8 connect by rownum <= 10;
9 for i in 1..v_x.count
10 loop
11 dbms_output.put_line(to_char(v_x(i)));
12 end loop;
13 end;
14 /
1
2
3
4
5
6
7
8
9
10
PL/SQL procedure successfully completed.
SQL> ed
Wrote file afiedt.buf
1 declare
2 type t_x is table of number index by binary_integer;
3 v_x t_x;
4 begin
5 select rownum
6 bulk collect into v_x
7 from dual
8 where 1=0;
9 for i in 1..v_x.count
10 loop
11 dbms_output.put_line(to_char(v_x(i)));
12 end loop;
13* end;
SQL> /
PL/SQL procedure successfully completed. -
UNION operator with BULK COLLECT for a collection type
Hi all,
I created a table type as below:
create or replace type coltest is table of number;
Below are 3 PL/SQL blocks that populate data into variables of the above mentioned table type:
BLOCK 1:
DECLARE
col1 coltest := coltest(1, 2, 3, 4, 5, 11);
col2 coltest := coltest(6, 7, 8, 9, 10);
col3 coltest := coltest();
BEGIN
SELECT * BULK COLLECT
INTO col1
FROM (SELECT *
FROM TABLE(CAST(col1 AS coltest))
UNION ALL
SELECT * FROM TABLE(CAST(col2 AS coltest)));
dbms_output.put_line('col1');
dbms_output.put_line('col1.count: ' || col1.COUNT);
FOR i IN 1 .. col1.COUNT
LOOP
dbms_output.put_line(col1(i));
END LOOP;
END;
OUPUT:
col1
col1.count: 5
6
7
8
9
10
BLOCK 2:
DECLARE
col1 coltest := coltest(1, 2, 3, 4, 5, 11);
col2 coltest := coltest(6, 7, 8, 9, 10);
col3 coltest := coltest();
BEGIN
SELECT * BULK COLLECT
INTO col2
FROM (SELECT *
FROM TABLE(CAST(col1 AS coltest))
UNION ALL
SELECT * FROM TABLE(CAST(col2 AS coltest)));
dbms_output.put_line('col2');
dbms_output.put_line('col2.count: ' || col2.COUNT);
FOR i IN 1 .. col2.COUNT
LOOP
dbms_output.put_line(col2(i));
END LOOP;
END;
OUTPUT:
col2
col2.count: 6
1
2
3
4
5
11
BLOCK 3:
DECLARE
col1 coltest := coltest(1, 2, 3, 4, 5, 11);
col2 coltest := coltest(6, 7, 8, 9, 10);
col3 coltest := coltest();
BEGIN
SELECT * BULK COLLECT
INTO col3
FROM (SELECT *
FROM TABLE(CAST(col1 AS coltest))
UNION ALL
SELECT * FROM TABLE(CAST(col2 AS coltest)));
dbms_output.put_line('col3');
dbms_output.put_line('col3.count: ' || col3.COUNT);
FOR i IN 1 .. col3.COUNT
LOOP
dbms_output.put_line(col3(i));
END LOOP;
END;
OUTPUT:
col3
col3.count: 11
1
2
3
4
5
11
6
7
8
9
10
Can anyone please explain the output of BLOCK 1 and 2? Why doesn't bulk collect into col1 and col2 return 11 as count?Consider the following code from your block.
select *
bulk collect into col1
from (
select *
from table(cast(col1 as coltest))
union
all
select *
from table(cast(col2 as coltest))
); Now my assumption would be like this.
PL/SQL engine would recognize the SQL part and will be sending it to SQL Engine for processing. Before doing that it will try to initialize the SQL collection variable COL1. Now when SQL Engine process the SELECT, COL1 would be empty already. And thats the reason you don't get the as 5 and not 11. -
Where to put the commit in the FORALL BULK COLLECT LOOP
Hi,
Have the following LOOP code using FORALL and bulk collect, but didnt know where to put the
'commit' :
open f_viewed;
LOOP
fetch f_viewed bulk collect into f_viewed_rec LIMIT 2000;
forall i in 1..f_viewed_rec.count
insert into jwoodman.jw_job_history_112300
values f_viewed_rec(i);
--commit; [Can I put this 'commit' here? - Jenny]
EXIT when f_viewed%NOTFOUND;
END LOOP;
commit;
Thanks,
- Jennymc**** wrote:
Bulk collect normally used with large data sets. If you have less dataset such as 1000-2000 records then you canot get such a performance improvent using bulk collect.(Please see oracle documents for this)
When you update records Oracle acquire exclusive lock for that. So if you use commit inside the loop then it will process number of records defined by limit parameter at ones and then commit those changes.
That will release all locks acquired by Oracle and also teh memory used to keep those uncommited transactions.
If you use commit outside the loop,
Just assume that you insert 100,000 records, all those records will store in oracle memory and it will affect all other users performance as well.
Further more if you update 100,000 records then it will hold exclusive lock for all 100,000 records addtion to the usage of the oracle memory.
I am using this for telco application which we process over 30 million complex records (one row has 234 columns).
When we work with large data sets we do not depends with the oracle basic rollback function. because when you keep records without commit itb uses oracle memory and badly slowdown all other processes.Hi mc****,
What a load of dangerous and inaccurate rubbish to be telling a new Oracle developer. Commit processing should be driven by the logical unit of a transaction. This should hold true whether that transaction involves a few rows or millions. If, and only if, the transaction is so large that it affects the size constraints of the database resources, in particular, rollback or redo space, then you can consider breaking that transaction up to smaller transactions.
Why is frequent committing undesirable I hear you ask?
First of all it is hugely wasteful of rollback or redo space. This is because while the database is capable of locking at a row level, redo is written at a block level, which means that if you update, delete or insert a million rows and commit after each individual statement, then that is a million blocks that need to go into redo. As many of these rows will be in the same block, if you instead do these as one transaction, then the same block in redo can be transacted upon, making the operation more efficient. True, locks will be held for longer, but if this is new data being done in batches then users will rarely be inconvenienced. If locking is a problem then I would suggest that you should be looking at how you are doing your processing.
Secondly, committing brings into play one of the major serialization points in the database, log sync. When a transaction is committed, the log buffer needs to be written to disc. This occurs serially for multiple commits. Each commit has to wait until the commit before has completed. This becomes even more of a bottleneck if you are using Data Guard in SYNC mode, as the commit cycle does not complete until the remote log is notified as written.
This then brings us two rules of thumb that will always lead a developer in the right direction.
1. Commit as infrequently as possible, usually at the logical unit of a transaction
2. When building transactions, first of all seek to do it using straight SQL (CTAS, insert select, update where etc). If this can't be easily achieved, then use PL/SQL bulk operations.
Regards
Andre -
Bulk collect into using vector in where clause
Hi,
I have a java stored procedure which takes an array as input and returns an array as output.
I want to select a column in to a collection of array, using array as the select criteria.
For example
create or replace type My_list as table of varchar(20);
create or replace type outarray as table of BLOB;
create or replace function myfunction ( inputlist My_list)
return outarray
AS
o_data := outarray();
BEGIN
SELECT mycolumn from mytable BULK COLLECT INTO o_data where my_creteria=inputlist
retrun o_data;
END;
Unless I use FORALL I can not retrieve the inputlist values. I am not sure how I can use the bulk collect and forall in the same statement?
My data is arranged such that , for each value in the inputlist one row will be fetched. I want to fetch all these rows at one go using the inputlist as select criteria,
I can use the for i in inputlist.first .. inputlist.LAST and iterate the inputlist but that process is quite expensive interms of the latency.
You help in optimizing my query would be highly appreciated.
Regards,
SyamThat only leaves ugly solutions, like:
<ul>
<li>Using dynamic SQL to create a temporary table, doing a bulk insert of the incoming array and then reading the table values using a subquery with the IN opeartor.</li>
<li>Building a dyanmic list, like ('value1','value2', ..) and use it with the IN operator, this is a variable list and requires DBMS_SQL package.</li>
<li>Ignore the bulk operations. :-(</li>
</ul> -
Hi All,
I've one doubt regarding the bulk operations using the forall statement.
Check below eample:
CREATE TABLE emp_temp AS SELECT * FROM employees;
DECLARE
TYPE empid_tab IS TABLE OF employees.employee_id%TYPE;
emp_sr empid_tab;
-- create an exception handler for ORA-24381
errors NUMBER;
dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(dml_errors, -24381);
BEGIN
SELECT employee_id BULK COLLECT INTO emp_sr FROM emp_temp
WHERE hire_date < '30-DEC-94';
-- add '_SR' to the job_id of the most senior employees
FORALL i IN emp_sr.FIRST..emp_sr.LAST SAVE EXCEPTIONS
UPDATE emp_temp SET job_id = job_id || '_SR'
WHERE emp_sr(i) = emp_temp.employee_id;
-- If any errors occurred during the FORALL SAVE EXCEPTIONS,
-- a single exception is raised when the statement completes.
EXCEPTION
WHEN dml_errors THEN -- Now we figure out what failed and why.
errors := SQL%BULK_EXCEPTIONS.COUNT;
DBMS_OUTPUT.PUT_LINE('Number of statements that failed: ' || 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('Error message is ' ||
SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
END;
Here we update using bulk collect & the exceptions for each iterations are kept separately.
In case, I want to know whether the sql statements in each array are executed separately or all the statements are executed in bulk?
Thanks
DeepakMay this will answer it...
FORALL - documentation -
How to handle the bad record while using bulk collect with limit.
Hi
How to handle the Bad record as part of the insertion/updation to avoid the transaction.
Example:
I am inserting into table with LIMIT of 1000 records and i've got error at 588th record.
i want to commit the transaction with 588 inserted record in table and log the error into
error logging table then i've to continue with transaction with 560th record.
Can anyone suggest me in this case.
Regards,
yuva>
How to handle the Bad record as part of the insertion/updation to avoid the transaction.
>
Use the SAVE EXCEPTIONS clause of the FORALL if you are doing bulk inserts.
See SAVE EXCEPTIONS in the PL/SQL Language doc
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/tuning.htm
And then see Example 12-9 Bulk Operation that continues despite exceptions
>
Example 12-9 Bulk Operation that Continues Despite Exceptions
-- Temporary table for this example:
CREATE TABLE emp_temp AS SELECT * FROM employees;
DECLARE
TYPE empid_tab IS TABLE OF employees.employee_id%TYPE;
emp_sr empid_tab;
-- Exception handler for ORA-24381:
errors NUMBER;
dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(dml_errors, -24381);
BEGIN
SELECT employee_id
BULK COLLECT INTO emp_sr FROM emp_temp
WHERE hire_date < '30-DEC-94';
-- Add '_SR' to job_id of most senior employees:
FORALL i IN emp_sr.FIRST..emp_sr.LAST SAVE EXCEPTIONS
UPDATE emp_temp SET job_id = job_id || '_SR'
WHERE emp_sr(i) = emp_temp.employee_id;
-- If errors occurred during FORALL SAVE EXCEPTIONS,
-- a single exception is raised when the statement completes.
EXCEPTION
-- Figure out what failed and why
WHEN dml_errors THEN
errors := SQL%BULK_EXCEPTIONS.COUNT;
DBMS_OUTPUT.PUT_LINE
('Number of statements that failed: ' || 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('Error message is ' ||
SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
END;
DROP TABLE emp_temp; -
Any way to use cursor values inside other cursor by bulk collect?
hi,
Is there any way to use cursor get_tables value insdide loop get column if i am using bulk collect in both cursors?
I tried a lot but i am nt able to do it.kindly help...
create or replace procedure MULTIPLE_CURSORS_PROC is
v_owner varchar2(40);
v_table_name varchar2(40);
v_column_name varchar2(100);
cursor get_tables is
select distinct tbl.owner, tbl.table_name
from all_tables tbl
where tbl.owner = 'SYSTEM';
cursor get_columns is
select distinct col.column_name
from all_tab_columns col
where col.owner = v_owner
and col.table_name = v_table_name;
begin
open get_tables;
loop
fetch get_tables into v_owner, v_table_name;
open get_columns;
loop
fetch get_columns into v_column_name;
end loop;
close get_columns;
end loop;
close get_tables;
end ;hi there
Refer this
CREATE OR REPLACE PROCEDURE MULTIPLE_CURSORS_PROC
IS
TYPE scol IS VARRAY (10000) OF VARCHAR2 (32767);
v_table_name scol;
v_column_name scol;
TYPE curtyp IS REF CURSOR;
get_columns curtyp;
CURSOR get_tables
IS
SELECT DISTINCT tbl.table_name
FROM all_tables tbl
WHERE tbl.owner = 'SYSTEM';
BEGIN
OPEN get_tables;
LOOP
FETCH get_tables BULK COLLECT INTO v_table_name;
FOR indx IN v_table_name.FIRST .. v_table_name.LAST
LOOP
SELECT DISTINCT col.column_name
BULK COLLECT
INTO v_column_name
FROM all_tab_columns col
WHERE col.table_name = v_table_name (indx);
FOR ind IN v_column_name.FIRST .. v_column_name.LAST
LOOP
DBMS_OUTPUT.put_line (v_column_name (ind));
END LOOP;
END LOOP;
EXIT WHEN get_tables%NOTFOUND;
END LOOP;
CLOSE get_tables;
END MULTIPLE_CURSORS_PROC;regards
Hitesh -
Use of FOR Cursor and BULK COLLECT INTO
Dear all,
in which case we prefer to use FOR cursor and cursor with BULK COLLECT INTO? The following contains two block that query identically where one is using FOR cursor, the other is using BULK COLLECT INTO . Which one that performs better given in the existing task? How do we measure performance between these two?
I'm using sample HR schema:
declare
l_start number;
BEGIN
l_start:= DBMS_UTILITY.get_time;
dbms_lock.sleep(1);
FOR employee IN (SELECT e.last_name, j.job_title FROM employees e,jobs j
where e.job_id=j.job_id and e.job_id LIKE '%CLERK%' AND e.manager_id > 120 ORDER BY e.last_name)
LOOP
DBMS_OUTPUT.PUT_LINE ('Name = ' || employee.last_name || ', Job = ' || employee.job_title);
END LOOP;
DBMS_OUTPUT.put_line('total time: ' || to_char(DBMS_UTILITY.get_time - l_start) || ' hsecs');
END;
declare
l_start number;
type rec_type is table of varchar2(20);
name_rec rec_type;
job_rec rec_type;
begin
l_start:= DBMS_UTILITY.get_time;
dbms_lock.sleep(1);
SELECT e.last_name, j.job_title bulk collect into name_rec,job_rec FROM employees e,jobs j
where e.job_id=j.job_id and e.job_id LIKE '%CLERK%' AND e.manager_id > 120 ORDER BY e.last_name;
for j in name_rec.first..name_rec.last loop
DBMS_OUTPUT.PUT_LINE ('Name = ' || name_rec(j) || ', Job = ' || job_rec(j));
END LOOP;
DBMS_OUTPUT.put_line('total time: ' || to_char(DBMS_UTILITY.get_time - l_start) || ' hsecs');
end;
/In this code, I put timestamp in each block, but they are useless since they both run virtually instantaneous...
Best regards,
ValIf you want to get 100% benifit of bulk collect then it must be implemented as below
declare
Cursor cur_emp
is
SELECT e.last_name, j.job_title
FROM employees e,jobs j
where e.job_id=j.job_id
and e.job_id LIKE '%CLERK%'
AND e.manager_id > 120
ORDER BY e.last_name;
l_start number;
type rec_type is table of varchar2(20);
name_rec rec_type;
job_rec rec_type;
begin
l_start:= DBMS_UTILITY.get_time;
dbms_lock.sleep(1);
/*SELECT e.last_name, j.job_title bulk collect into name_rec,job_rec FROM employees e,jobs j
where e.job_id=j.job_id and e.job_id LIKE '%CLERK%' AND e.manager_id > 120 ORDER BY e.last_name;
OPEN cur_emp;
LOOP
FETCH cur_emp BULK COLLECT INTO name_rec LIMIT 100;
EXIT WHEN name_rec.COUNT=0;
FOR j in 1..name_rec.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE ('Name = ' || name_rec(j) || ', Job = ' || job_rec(j));
END LOOP;
EXIT WHEN cur_emp%NOTFOUND;
END LOOP;
CLOSE cur_emp;
DBMS_OUTPUT.put_line('total time: ' || to_char(DBMS_UTILITY.get_time - l_start) || ' hsecs');
end;
/ -
Is there a way to BULK COLLECT with FOR UPDATE and not lock ALL the rows?
Currently, we fetch a cursor on a few million rows using BULK COLLECT.
In a FORALL loop, we update the rows.
What is happening now, is that we run this procedure at the same time, and there is another session running a MERGE statement on the same table, and a DEADLOCK is created between them.
I'd like to add to the cursor the FOR UPDATE clause, but from what i've read,
it seems that this will cause ALL the rows in the cursor to become locked.
This is a problem, as the other session is running MERGE statements on the table every few seconds, and I don't want it to fail with ORA-0054 (resource busy).
What I would like to know is if there is a way, that only the rows in the
current bulk will be locked, and all the other rows will be free for updates.
To reproduce this problem:
1. Create test table:
create table TEST_TAB
ID1 VARCHAR2(20),
ID2 VARCHAR2(30),
LAST_MODIFIED DATE
2. Add rows to test table:
insert into TEST_TAB (ID1, ID2, LAST_MODIFIED)
values ('416208000770698', '336015000385349', to_date('15-11-2009 07:14:56', 'dd-mm-yyyy hh24:mi:ss'));
insert into TEST_TAB (ID1, ID2, LAST_MODIFIED)
values ('208104922058401', '336015000385349', to_date('15-11-2009 07:11:15', 'dd-mm-yyyy hh24:mi:ss'));
insert into TEST_TAB (ID1, ID2, LAST_MODIFIED)
values ('208104000385349', '336015000385349', to_date('15-11-2009 07:15:13', 'dd-mm-yyyy hh24:mi:ss'));
3. Create test procedure:
CREATE OR REPLACE PROCEDURE TEST_PROC IS
TYPE id1_typ is table of TEST_TAB.ID1%TYPE;
TYPE id2_typ is table of TEST_TAB.ID2%TYPE;
id1_arr id1_typ;
id2_arr id2_typ;
CURSOR My_Crs IS
SELECT ID1, ID2
FROM TEST_TAB
WHERE ID2 = '336015000385349'
FOR UPDATE;
BEGIN
OPEN My_Crs;
LOOP
FETCH My_Crs bulk collect
INTO id1_arr, id2_arr LIMIT 1;
Forall i in 1 .. id1_arr.COUNT
UPDATE TEST_TAB
SET LAST_MODIFIED = SYSDATE
where ID2 = id2_arr(i)
and ID1 = id1_arr(i);
dbms_lock.sleep(15);
EXIT WHEN My_Crs%NOTFOUND;
END LOOP;
CLOSE My_Crs;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20000,
'Test Update ' || SQLCODE || ' ' || SQLERRM);
END TEST_PROC;
4. Create another procedure to check if table rows are locked:
create or replace procedure check_record_locked(p_id in TEST_TAB.ID1%type) is
cursor c is
select 'dummy'
from TEST_TAB
WHERE ID2 = '336015000385349'
and ID1 = p_id
for update nowait;
e_resource_busy exception;
pragma exception_init(e_resource_busy, -54);
begin
open c;
close c;
dbms_output.put_line('Record ' || to_char(p_id) || ' is not locked.');
rollback;
exception
when e_resource_busy then
dbms_output.put_line('Record ' || to_char(p_id) || ' is locked.');
end check_record_locked;
5. in one session, run the procedure TEST_PROC.
6. While it's running, in another session, run this block:
begin
check_record_locked('208104922058401');
check_record_locked('416208000770698');
check_record_locked('208104000385349');
end;
7. you will see that all records are identified as locked.
Is there a way that only 1 row will be locked, and the other 2 will be unlocked?
Thanks,
Yoni.I don't have database access on weekends (look at it as a template)
suppose you
create table help_iot
(bucket number,
id1 varchar2(20),
constraint help_iot_pk primary key (bucket,id1)
organization index;not very sure about the create table syntax above.
declare
maximal_bucket number := 10000; -- will update few hundred rows at a time if you must update few million rows
the_sysdate date := sysdate;
begin
truncate table help_iot;
insert into help_iot
select ntile(maximal_bucket) over (order by id1) bucket,id1
from test_tab
where id2 = '336015000385349';
for i in 1 .. maximal_bucket
loop
select id1,id2,last_modified
from test_tab
where id2 = '336015000385349'
and id1 in (select id1
from help_iot
where bucket = i
for update of last_modified;
update test_tab
set last_modified = the_sysdate
where id2 = '336015000385349'
and id1 in (select id1
from help_iot
where bucket = i
commit;
dbms_lock.sleep(15);
end loop;
end;Regards
Etbin
introduced the_sysdate if last_modified must be the same for all updated rows
Edited by: Etbin on 29.11.2009 16:48 -
How can I fill a table of objects from cursor with select * bulk collect???
Hi All, I have a TYPE as OBJECT
create or replace type dept2_o as object (
deptno NUMBER(2),
dname VARCHAR2(14),
loc VARCHAR2(13));
I can fill a table of objects from cursor with out select * bulk collect...., row by row
declare
TYPE dept2_t IS TABLE of dept2_o;
dept_o_tab dept2_t:=dept2_t();
i integer;
begin
i:=0;
dept_o_tab.extend(20);
for rec in (select * from dept) loop
i:=i+1;
dept_o_tab(i):=dept2_o(
deptno => rec.deptno,
dname => rec.dname,
loc =>rec.loc
end loop;
for k IN 1..i loop
dbms_output.put_line(dept_o_tab(k).deptno||' '||dept_o_tab(k).dname||' '||dept_o_tab(k).loc);
end loop;
end;
RESULT
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
But I can't fill a table of objects from cursor with select * bulk collect construction ...
declare
TYPE dept2_t IS TABLE of dept2_o;
dept_o_tab dept2_t:=dept2_t();
begin
dept_o_tab.extend(20);
select * bulk collect into dept_o_tab from dept;
end;
RESULT
ORA-06550: line 6, column 39;
PL/SQL: ORA-00947: not enough values ....
How can I fill a table of objects from cursor with select * bulk collect???create or replace type dept_ot as object (
deptno NUMBER(2),
dname VARCHAR2(14),
loc VARCHAR2(13));
create table dept
(deptno number
,dname varchar2(14)
,loc varchar2(13)
insert into dept values (10, 'x', 'xx');
insert into dept values (20, 'y', 'yy');
insert into dept values (30, 'z', 'zz');
select dept_ot (deptno, dname, loc)
from dept
create type dept_nt is table of dept_ot
declare
l_depts dept_nt;
begin
select dept_ot (deptno, dname, loc)
bulk collect
into l_depts
from dept
for i in l_depts.first .. l_depts.last
loop
dbms_output.put_line (l_depts(i).deptno);
dbms_output.put_line (l_depts(i).dname);
dbms_output.put_line (l_depts(i).loc);
end loop;
end;
/ -
ORA-01722: invalid number error with Bulk collect
Hi ,
I have been using the script to delete old seasonal data from my application DB tables. The stored procedure has been created successfully but when i try to run the proc it has been throwing 'ORA-01722: invalid number' exception at line 'FETCH C1_CUR BULK COLLECT INTO C1_TYPE_VAR LIMIT v_bulklimit;'.
Could you please help me here?
Below is the stored proc:
CREATE OR REPLACE PROCEDURE clean_old_season_data(P_SEASON VARCHAR2) AS
CURSOR C1_CUR IS SELECT ROWID RID,pro.* FROM PROPS pro where pro.ITEMPK IN
(SELECT sve.pk FROM SAVEDVALUEENTRY sve WHERE sve.p_parent IN
(SELECT s.pk FROM SAVEDVALUES s WHERE s.P_MODIFIEDITEM IN
(SELECT a.PK
FROM products a
WHERE a.p_season IN (select s.pk from Seasons s where s.P_code=P_SEASON)
) ) ) and rownum<5;
CURSOR C2_DEL IS SELECT RID FROM PROPS_HISTORY;
TYPE C1_TYPE IS TABLE OF C1_CUR%ROWTYPE;
C1_TYPE_VAR C1_TYPE;
TYPE C2_TYPE IS TABLE OF UROWID;
C2_TYPE_VAR C2_TYPE;
ex_dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(ex_dml_errors, -24381);
l_error_count NUMBER;
err_num NUMBER;
err_msg VARCHAR2 (300);
COMMIT_VARIABLE PLS_INTEGER:=0;
v_bulklimit NUMBER:=2;
BEGIN
/*------------------ Data Selection and INSERTION IN HISTORY TABLE ---------------------------------------*/
OPEN C1_CUR;
LOOP
DBMS_OUTPUT.put_line('Cursor opend now in loop');
FETCH C1_CUR BULK COLLECT INTO C1_TYPE_VAR LIMIT v_bulklimit;//ERROR OCCURS HERE
DBMS_OUTPUT.put_line('Cursor count is'|| C1_TYPE_VAR.COUNT);
FORALL I IN 1..C1_TYPE_VAR.COUNT SAVE EXCEPTIONS
INSERT INTO PROPS_HISTORY VALUES C1_TYPE_VAR(I);
COMMIT_VARIABLE := COMMIT_VARIABLE + v_bulklimit;
DBMS_OUTPUT.put_line('Commit variable'|| COMMIT_VARIABLE.COUNT);
IF COMMIT_VARIABLE = v_bulklimit THEN
COMMIT;
COMMIT_VARIABLE := 0;
END IF;
EXIT WHEN C1_CUR%NOTFOUND;
END LOOP;
DBMS_OUTPUT.put_line('Cursor closed now in loop and data inserted in history table');
CLOSE C1_CUR;
/*------------------ Data Selection and DELETION IN Live TABLE ---------------------------------------*/
COMMIT_VARIABLE := 0;
OPEN C2_DEL;
LOOP
FETCH C2_DEL BULK COLLECT INTO C2_TYPE_VAR LIMIT 2;
FORALL I IN 1..C2_TYPE_VAR.COUNT SAVE EXCEPTIONS
DELETE FROM PROPS WHERE ROWID = C2_TYPE_VAR(I);
COMMIT_VARIABLE := COMMIT_VARIABLE + 2;
IF COMMIT_VARIABLE = 2 THEN
COMMIT;
COMMIT_VARIABLE := 0;
END IF;
EXIT WHEN C2_DEL%NOTFOUND;
END LOOP;
CLOSE C2_DEL;
END;Although there are many things which should not have been done in the posted code, I could not find any reason why the Invalid number error should occur at the Fetch clause.
I would suggest you to Insert into Table by providing the Order of Columns i.e. Insert into table (col1, ... colN) values (coll(i).col1...col(i).colN);
I tested below code and it did not give any errors.
drop table test_table;
create table test_Table
rid varchar2(100),
emp_id number(5),
fname varchar2(20),
lname varchar2(50)
set serveroutput on;
declare
cursor c_cur is
select rowid rid, e.*
from employees e
where rownum < 10;
type typ_cur is table of c_cur%rowtype;
typ typ_cur;
l_bulk_limit number := 5;
begin
open c_cur;
loop
fetch c_cur bulk collect into typ limit l_bulk_limit;
dbms_output.put_line('Collection Count :: ' || typ.count);
forall i in 1..typ.count --typ.first..typ.last
insert into test_Table (rid, emp_id, fname, lname) values (typ(i).rid,typ(i).employee_id,typ(i).first_name,typ(i).last_name);
dbms_output.put_line('Processed ' || l_bulk_limit || ' records.');
exit when c_cur%notfound;
end loop;
commit;
end;
select * from test_table;PS:- 1. When you are processing only 4 Records, then why are you breaking them in 2 Loops?
2. Why Commit every time you are processing a DML? Why not maintain an Error Flag and Rollback the Transaction as soon as error is encountered?
3. Use "{code}" (Exclude Double Quotes) to format the code. I am not sure if works.
Regards,
P. -
Procedure failed while using bulk collect into clause and works with cursor
hi all,
I am using "BULK collect into" clause in my procedure and it is failing after 21 minutes and gives the error "end of file communication channel".
after this error comes when i tried to connect database it is giving following error.
ORA -01034 - Oracle not available.
ORA- 27101 - shared memory realm does not exist.
svr4- error :2 : No such file or directory.
when i use cursor instead of BULK COLLECT INTO clause it is running successful.
Following code is working with cursor.
procedure work_kiosk_full(an_jobid in number ,ac_sqlcode out varchar2 ,ac_sqlerrm out varchar2) is
ld_curr_time Date;
cursor cur_work_kiosk is
select distinct jt.jt_id AS jt_id,
NVL ((ROUND ((jt_date_completed - jt_date_requested) * 24, 2)
0
) AS actual_hrs_to_complete,
NVL ((ROUND ((jt_date_responded - jt_date_requested) * 24, 2)
0
) AS actual_hrs_to_respond,
peo1.peo_name AS agent_name,
peo1.peo_user_name AS asagent_soe_id,
le.lglent_desc AS ap_system,
' ' AS assign_work_request_comment,
DECODE (jt.jt_bill_id,
138802, 'CLIENT BILLABLE',
138803, 'CONTRACTED',
138804, 'INTERNAL BILLABLE',
NULL, ' '
) AS billable,
bl.bldg_name_cc AS building, bl.bldg_id_ls AS building_id,
DECODE (bl.bldg_active_cc,
'Y', 'ACTIVE',
'INACTIVE'
) AS building_status,
DECODE (jt.jt_wrk_cause_id,
141521, 'STANDARD WEAR AND TEAR',
141522, 'NEGLIGENCE',
141523, 'ACCIDENTAL',
141524, 'MECHANICAL MALFUNCTION',
141525, 'OVERSIGHT',
141526, 'VANDAL',
141527, 'STANDARD',
141528, 'PROJECT WORK',
6058229, 'TEST',
NULL, ' '
) AS cause_type,
' ' AS comments, peo3.peo_name AS completed_by,
jt.jt_requestor_email AS contact_email,
jt.jt_requestor_name_first
|| ' '
|| jt.jt_requestor_name_last AS contact_name,
jt.jt_requestor_phone AS contact_phone,
cc.cstctrcd_apcode AS corp_code,
cc.cstctrcd_code AS cost_center,
jt.jt_date_closed AS date_closed,
jt.jt_date_completed AS date_completed,
jt.jt_date_requested AS date_requested,
jt.jt_date_responded AS date_responded,
jt.jt_date_response_ecd AS date_response_ecd,
jt.jt_date_scheduled AS date_scheduled,
DECODE (jt.jt_def_id,
139949, 'WTG VENDOR RESPONSE',
139950, 'WAITING ON PARTS',
139951, 'LABOR AVAILABILITY',
139952, 'DEFERRED- HI PRI WORK',
139953, 'WTG APPROVAL',
139954, 'FUNDING REQUIRED',
139955, 'ACCESS DENIED',
139956, 'WTG MATERIAL',
NULL, ' '
) AS deferral_reason,
jt.jt_description AS description,
jt.jt_date_resched_ecd AS ecd,
fmg.facility_manager AS facility_manager,
fl.floors_text AS FLOOR, gl.genled_desc AS general_ledger,
' ' AS kiosk_date_requested, ' ' AS kiosk_dispatch_confirmed,
' ' AS kiosk_dispatched,
eqp.equip_customer_code AS linked_equipment_alias,
eqp.equip_id AS linked_equipment_id,
eqp.equip_text AS linked_equipment_name,
DECODE (jt_originator_type_id,
1000, 'PROJECT MOVE REQUEST',
138834, 'CUSTOMER INITIATED CORRECTION',
138835, 'CUSTOMER INITIATED REQUEST',
138836, 'CORRECTIVE MAINTENANCE',
138837, 'CONFERENCE ROOM BOOKING',
138838, 'PROJECT INITIATED REQUEST',
138839, 'PLANNED PREVENTIVE MAINTENANCE',
138840, 'SELF INITATED REQUEST',
NULL, ' '
) AS originator_type,
' ' AS payment_terms, priority_text AS priority_code,
swoty.sworktype_text AS problem_type,
prop.property_name_cc AS property,
jt.jt_cost_quote_total AS quote_total,
par.levels_name AS region,
DECODE (jt.jt_repdef_id,
141534, 'ADJUSTED SETTING',
141535, 'TRAINING FOR END',
141536, 'NEW REQUEST',
141537, 'NO REPAIR REQUIR',
141538, 'REPLACED PARTS',
141539, 'REPLACE EQUIPMEN',
1000699, 'NEW REQUEST',
NULL, ' '
) AS repair_definitions,
jt.jt_repairdesc AS repair_description,
jt.jt_requestor AS requestor, ' ' AS requestor_cost_center,
jt.jt_requestor_email AS requestor_email,
jt.jt_requestor_name_first AS requestor_name,
jt.jt_requestor_phone AS requestor_phone,
' ' AS response_time, rm.room_name_cc AS room,
p1.peo_provider_code1 AS service_provider,
p1.peo_address_1 AS service_provider_address,
peocity.city_text service_provider_city,
p1.peo_provider_code1 AS service_provider_code,
peocity.city_country_name AS service_provider_country,
peocur.currency_text AS service_provider_currency,
p1.peo_name AS service_provider_description,
p1.peo_dispatch_method AS serv_prov_dispatc_hmethod,
p1.peo_rate_double AS serv_prov_double_time_rate,
p1.peo_email AS service_provider_email,
p1.peo_emergency_phone AS serv_prov_emergency_phone,
p1.peo_fax AS service_provider_fax_number,
p1.peo_home_phone AS service_provider_home_phone,
p1.peo_rate_hourly AS service_provider_hourly_rate,
p1.peo_title AS service_provider_job_title,
p1.peo_method_id AS service_provider_method,
p1.peo_cell_phone AS service_provider_mobile_phone,
p1.peo_pager AS service_provider_pager,
p1.peo_rate_differential AS service_provider_rates,
p1.peo_rate_differential AS ser_prov_shift_differential,
peocity.city_state_prov_text AS serv_prov_state_province,
DECODE (p1.peo_active,
'Y', 'ACTIVE',
'INACTIVE'
) AS service_provider_status,
p1.peo_url AS serv_prov_web_site_address,
p1.peo_phone AS service_provider_work_phone,
p1.peo_postal_code AS serv_prov_zip_postal_code, ' ' AS shift,
' ' AS skill,
DECODE (jt.jt_bigstatus_id,
138813, 'NEW',
138814, 'PENDING',
138815, 'OPEN',
138816, 'COMPLETED',
138817, 'CLOSED',
138818, 'CANCELLED',
NULL, ' '
) AS status,
lev.levels_name AS subregion, ' ' AS trade,
p1.peo_ls_interface_code1 AS vendor_id,
p1.peo_fax AS vendor_purchasing_fax,
p1.peo_vendor_site_code AS vendor_sitecode,
jt.jt_id AS vendor_ticket, p1.peo_name AS vendor_companyname,
jt.jt_requestor_vip AS vip, wo.wo_id AS work_order_no,
jt.jt_id AS work_request,
jt.jt_class_id AS work_request_class,
woty.worktype_text AS work_type, ' ' AS wr_cost,
jt.jt_description AS wr_description,
' ' AS wr_dispatch_method,
DECODE (jt.jt_bigstatus_id,
138813, 'NEW',
138814, 'PENDING',
138815, 'OPEN',
138816, 'COMPLETED',
138817, 'CLOSED',
138818, 'CANCELLED',
NULL, ' '
) AS wr_status,
ctry.country_name AS country
FROM citi.jobticket jt,
citi.property prop,
citi.bldg bl,
citi.bldg_levels bldglvl,
citi.LEVELS lev,
citi.LEVELS par,
(SELECT crstools.stragg (peo_name) facility_manager,
bldgcon_bldg_id
FROM citi.bldg_contacts, citi.people
WHERE bldgcon_peo_id = peo_id
AND bldgcon_contype_id IN (40181, 10142)
GROUP BY bldgcon_bldg_id) fmg,
citi.floors fl,
citi.room rm,
citi.general_ledger gl,
citi.legal_entity le,
citi.cost_center_codes cc,
citi.equipment eqp,
citi.worktype woty,
citi.subworktype swoty,
citi.work_order wo,
citi.jt_workers jtwo,
citi.priority,
citi.country ctry,
citi.people p1,
citi.people peo3,
citi.people peo1,
citi.city peocity,
citi.currency peocur
WHERE jt.jt_bldg_id = bl.bldg_id
AND bl.bldg_id = bldglvl.bldg_levels_bldg_id
AND bldglvl.bldg_levels_levels_id = lev.levels_id
AND lev.levels_parent = par.levels_id(+)
AND prop.property_id = bl.bldg_property_id
AND bl.bldg_active_ls <> 'N'
AND jt.jt_floors_id = fl.floors_id(+)
AND jt.jt_room_id = rm.room_id(+)
AND jt.jt_bldg_id = fmg.bldgcon_bldg_id(+)
AND jt.jt_genled_id = gl.genled_id(+)
AND gl.genled_lglent_id = le.lglent_id(+)
AND jt.jt_cstctrcd_id = cc.cstctrcd_id(+)
AND jt.jt_equip_id = eqp.equip_id(+)
AND jt.jt_id = jtwo.jtw_jt_id(+)
AND jt.jt_worktype_id = woty.worktype_id(+)
AND jt.jt_sworktype_id = swoty.sworktype_id(+)
AND jt.jt_wo_id = wo.wo_id
AND jt.jt_priority_id = priority_id(+)
--AND jt.jt_date_requested >= ADD_MONTHS (SYSDATE, -12)
AND jt.jt_last_update >= ADD_MONTHS (ld_curr_time, -12)
AND bl.bldg_country_id = ctry.country_id
AND jtwo.jtw_peo_id = p1.peo_id(+)
AND p1.peo_city_id = peocity.city_id(+)
AND jt.jt_completed_by_peo_id = peo3.peo_id(+)
AND p1.peo_rate_currency_id = peocur.currency_id(+)
AND jt.jt_agent_peo_id = peo1.peo_id(+);
BEGIN
execute immediate 'truncate table crstools.drt_bom_work_kiosk';
select sysdate into ld_curr_time from dual;
FOR cur_rec in cur_work_kiosk LOOP
IF MOD(cur_work_kiosk%rowcount,10000 ) = 0 then
COMMIT;
END IF;
INSERT INTO crstools.drt_bom_work_kiosk
( JT_ID
,ACTUAL_HRS_TO_COMPLETE
,ACTUAL_HRS_TO_RESPOND
,AGENT_NAME
,ASAGENT_SOE_ID
,AP_SYSTEM
,ASSIGN_WORK_REQUEST_COMMENT
,BILLABLE
,BUILDING
,BUILDING_ID
,BUILDING_STATUS
,CAUSE_TYPE
,COMMENTS
,COMPLETED_BY
,CONTACT_EMAIL
,CONTACT_NAME
,CONTACT_PHONE
,CORP_CODE
,COST_CENTER
,DATE_CLOSED
,DATE_COMPLETED
,DATE_REQUESTED
,DATE_RESPONDED
,DATE_RESPONSE_ECD
,DATE_SCHEDULED
,DEFERRAL_REASON
,DESCRIPTION
,ECD
,FACILITY_MANAGER
,FLOOR
,GENERAL_LEDGER
,KIOSK_DATE_REQUESTED
,KIOSK_DISPATCH_CONFIRMED
,KIOSK_DISPATCHED
,LINKED_EQUIPMENT_ALIAS
,LINKED_EQUIPMENT_ID
,LINKED_EQUIPMENT_NAME
,ORIGINATOR_TYPE
,PAYMENT_TERMS
,PRIORITY_CODE
,PROBLEM_TYPE
,PROPERTY
,QUOTE_TOTAL
,REGION
,REPAIR_DEFINITIONS
,REPAIR_DESCRIPTION
,REQUESTOR
,REQUESTOR_COST_CENTER
,REQUESTOR_EMAIL
,REQUESTOR_NAME
,REQUESTOR_PHONE
,RESPONSE_TIME
,ROOM
,SERVICE_PROVIDER
,SERVICE_PROVIDER_ADDRESS
,SERVICE_PROVIDER_CITY
,SERVICE_PROVIDER_CODE
,SERVICE_PROVIDER_COUNTRY
,SERVICE_PROVIDER_CURRENCY
,SERVICE_PROVIDER_DESCRIPTION
,SERV_PROV_DISPATC_HMETHOD
,SERV_PROV_DOUBLE_TIME_RATE
,SERVICE_PROVIDER_EMAIL
,SERV_PROV_EMERGENCY_PHONE
,SERVICE_PROVIDER_FAX_NUMBER
,SERVICE_PROVIDER_HOME_PHONE
,SERVICE_PROVIDER_HOURLY_RATE
,SERVICE_PROVIDER_JOB_TITLE
,SERVICE_PROVIDER_METHOD
,SERVICE_PROVIDER_MOBILE_PHONE
,SERVICE_PROVIDER_PAGER
,SERVICE_PROVIDER_RATES
,SER_PROV_SHIFT_DIFFERENTIAL
,SERV_PROV_STATE_PROVINCE
,SERVICE_PROVIDER_STATUS
,SERV_PROV_WEB_SITE_ADDRESS
,SERVICE_PROVIDER_WORK_PHONE
,SERV_PROV_ZIP_POSTAL_CODE
,SHIFT
,SKILL
,STATUS
,SUBREGION
,TRADE
,VENDOR_ID
,VENDOR_PURCHASING_FAX
,VENDOR_SITECODE
,VENDOR_TICKET
,VENDOR_COMPANYNAME
,VIP
,WORK_ORDER_NO
,WORK_REQUEST
,WORK_REQUEST_CLASS
,WORK_TYPE
,WR_COST
,WR_DESCRIPTION
,WR_DISPATCH_METHOD
,WR_STATUS
,COUNTRY
,CREATE_DATE
VALUES
(cur_rec.jt_id
,cur_rec.ACTUAL_HRS_TO_COMPLETE
,cur_rec.ACTUAL_HRS_TO_RESPOND
,cur_rec.AGENT_NAME
,cur_rec.ASAGENT_SOE_ID
,cur_rec.AP_SYSTEM
,cur_rec.ASSIGN_WORK_REQUEST_COMMENT
,cur_rec.BILLABLE
,cur_rec.BUILDING
,cur_rec.BUILDING_ID
,cur_rec.BUILDING_STATUS
,cur_rec.CAUSE_TYPE
,cur_rec.COMMENTS
,cur_rec.COMPLETED_BY
,cur_rec.CONTACT_EMAIL
,cur_rec.CONTACT_NAME
,cur_rec.CONTACT_PHONE
,cur_rec.CORP_CODE
,cur_rec.COST_CENTER
,cur_rec.DATE_CLOSED
,cur_rec.DATE_COMPLETED
,cur_rec.DATE_REQUESTED
,cur_rec.DATE_RESPONDED
,cur_rec.DATE_RESPONSE_ECD
,cur_rec.DATE_SCHEDULED
,cur_rec.DEFERRAL_REASON
,cur_rec.DESCRIPTION
,cur_rec.ECD
,cur_rec.FACILITY_MANAGER
,cur_rec.FLOOR
,cur_rec.GENERAL_LEDGER
,cur_rec.KIOSK_DATE_REQUESTED
,cur_rec.KIOSK_DISPATCH_CONFIRMED
,cur_rec.KIOSK_DISPATCHED
,cur_rec.LINKED_EQUIPMENT_ALIAS
,cur_rec.LINKED_EQUIPMENT_ID
,cur_rec.LINKED_EQUIPMENT_NAME
,cur_rec.ORIGINATOR_TYPE
,cur_rec.PAYMENT_TERMS
,cur_rec.PRIORITY_CODE
,cur_rec.PROBLEM_TYPE
,cur_rec.PROPERTY
,cur_rec.QUOTE_TOTAL
,cur_rec.REGION
,cur_rec.REPAIR_DEFINITIONS
,cur_rec.REPAIR_DESCRIPTION
,cur_rec.REQUESTOR
,cur_rec.REQUESTOR_COST_CENTER
,cur_rec.REQUESTOR_EMAIL
,cur_rec.REQUESTOR_NAME
,cur_rec.REQUESTOR_PHONE
,cur_rec.RESPONSE_TIME
,cur_rec.ROOM
,cur_rec.SERVICE_PROVIDER
,cur_rec.SERVICE_PROVIDER_ADDRESS
,cur_rec.SERVICE_PROVIDER_CITY
,cur_rec.SERVICE_PROVIDER_CODE
,cur_rec.SERVICE_PROVIDER_COUNTRY
,cur_rec.SERVICE_PROVIDER_CURRENCY
,cur_rec.SERVICE_PROVIDER_DESCRIPTION
,cur_rec.SERV_PROV_DISPATC_HMETHOD
,cur_rec.SERV_PROV_DOUBLE_TIME_RATE
,cur_rec.SERVICE_PROVIDER_EMAIL
,cur_rec.SERV_PROV_EMERGENCY_PHONE
,cur_rec.SERVICE_PROVIDER_FAX_NUMBER
,cur_rec.SERVICE_PROVIDER_HOME_PHONE
,cur_rec.SERVICE_PROVIDER_HOURLY_RATE
,cur_rec.SERVICE_PROVIDER_JOB_TITLE
,cur_rec.SERVICE_PROVIDER_METHOD
,cur_rec.SERVICE_PROVIDER_MOBILE_PHONE
,cur_rec.SERVICE_PROVIDER_PAGER
,cur_rec.SERVICE_PROVIDER_RATES
,cur_rec.SER_PROV_SHIFT_DIFFERENTIAL
,cur_rec.SERV_PROV_STATE_PROVINCE
,cur_rec.SERVICE_PROVIDER_STATUS
,cur_rec.SERV_PROV_WEB_SITE_ADDRESS
,cur_rec.SERVICE_PROVIDER_WORK_PHONE
,cur_rec.SERV_PROV_ZIP_POSTAL_CODE
,cur_rec.SHIFT
,cur_rec.SKILL
,cur_rec.STATUS
,cur_rec.SUBREGION
,cur_rec.TRADE
,cur_rec.VENDOR_ID
,cur_rec.VENDOR_PURCHASING_FAX
,cur_rec.VENDOR_SITECODE
,cur_rec.VENDOR_TICKET
,cur_rec.VENDOR_COMPANYNAME
,cur_rec.VIP
,cur_rec.WORK_ORDER_NO
,cur_rec.WORK_REQUEST
,cur_rec.WORK_REQUEST_CLASS
,cur_rec.WORK_TYPE
,cur_rec.WR_COST
,cur_rec.WR_DESCRIPTION
,cur_rec.WR_DISPATCH_METHOD
,cur_rec.WR_STATUS
,cur_rec.COUNTRY
,ld_curr_time
END LOOP;
COMMIT;
exception
when others then
rollback;
dbms_output.put_line('SQLCODE :'||sqlcode ||' Error :'||sqlerrm);
end work_kiosk_full;
Note : total record inserted 849000.
The same code does not work with bulk collect into caluse.
Please help me out why this is happening.
Thanks & regards
shyam~Shyam,
I agree with Billy.
Why are you not using an INSERT..SELECT ?
Also, what are you trying to achieve by
- incremental commits?
- copying data from one table to another (using expensive I/O)?
- using dynamic DML?
Most of these approaches are typically wrong - and not recommended for scalable and performant Oracle applications.I could see you using a CURSOR FOR LOOP if you were changing the data being inserted in such a way that you couldn't encapsulate the changes in a query, but you are doing a straight insert into the table from your Cursor. A much more efficient way would be to use the following modifications I made to your code example:
PROCEDURE WORK_KIOSK_FULL(AN_JOBID IN NUMBER,
AC_SQLCODE OUT VARCHAR2,
AC_SQLERRM OUT VARCHAR2) IS
BEGIN
EXECUTE IMMEDIATE 'truncate table crstools.drt_bom_work_kiosk';
/* Note: The APPEND hint forces a Direct Path INSERT (see Link below code sample) and is combined with the NOLOGGING Hint */
/* To dramtically increase performance. The Direct Path INSERT inserts records above the High-Water Mark on the table. */
INSERT /*+ APPEND NOLOGGING */ INTO CRSTOOLS.DRT_BOM_WORK_KIOSK
(JT_ID
,ACTUAL_HRS_TO_COMPLETE
,ACTUAL_HRS_TO_RESPOND
,AGENT_NAME
,ASAGENT_SOE_ID
,AP_SYSTEM
-- ,ASSIGN_WORK_REQUEST_COMMENT /* I commented out this COLUMN because it doesn't make sense to me to insert */
,BILLABLE /* a couple of space characters into a table. If the intent is to leave the column NULL */
,BUILDING /* don't include it in your INSERT statement and it will be NULL. If there is a valid reason */
,BUILDING_ID /* for inserting the spaces, then remove the "line comments" from the insert and select statments */
,BUILDING_STATUS
,CAUSE_TYPE
-- ,COMMENTS
,COMPLETED_BY
,CONTACT_EMAIL
,CONTACT_NAME
,CONTACT_PHONE
,CORP_CODE
,COST_CENTER
,DATE_CLOSED
,DATE_COMPLETED
,DATE_REQUESTED
,DATE_RESPONDED
,DATE_RESPONSE_ECD
,DATE_SCHEDULED
,DEFERRAL_REASON
,DESCRIPTION
,ECD
,FACILITY_MANAGER
,FLOOR
,GENERAL_LEDGER
-- ,KIOSK_DATE_REQUESTED
-- ,KIOSK_DISPATCH_CONFIRMED
-- ,KIOSK_DISPATCHED
,LINKED_EQUIPMENT_ALIAS
,LINKED_EQUIPMENT_ID
,LINKED_EQUIPMENT_NAME
,ORIGINATOR_TYPE
-- ,PAYMENT_TERMS
,PRIORITY_CODE
,PROBLEM_TYPE
,PROPERTY
,QUOTE_TOTAL
,REGION
,REPAIR_DEFINITIONS
,REPAIR_DESCRIPTION
,REQUESTOR
-- ,REQUESTOR_COST_CENTER
,REQUESTOR_EMAIL
,REQUESTOR_NAME
,REQUESTOR_PHONE
-- ,RESPONSE_TIME
,ROOM
,SERVICE_PROVIDER
,SERVICE_PROVIDER_ADDRESS
,SERVICE_PROVIDER_CITY
,SERVICE_PROVIDER_CODE
,SERVICE_PROVIDER_COUNTRY
,SERVICE_PROVIDER_CURRENCY
,SERVICE_PROVIDER_DESCRIPTION
,SERV_PROV_DISPATC_HMETHOD
,SERV_PROV_DOUBLE_TIME_RATE
,SERVICE_PROVIDER_EMAIL
,SERV_PROV_EMERGENCY_PHONE
,SERVICE_PROVIDER_FAX_NUMBER
,SERVICE_PROVIDER_HOME_PHONE
,SERVICE_PROVIDER_HOURLY_RATE
,SERVICE_PROVIDER_JOB_TITLE
,SERVICE_PROVIDER_METHOD
,SERVICE_PROVIDER_MOBILE_PHONE
,SERVICE_PROVIDER_PAGER
,SERVICE_PROVIDER_RATES
,SER_PROV_SHIFT_DIFFERENTIAL
,SERV_PROV_STATE_PROVINCE
,SERVICE_PROVIDER_STATUS
,SERV_PROV_WEB_SITE_ADDRESS
,SERVICE_PROVIDER_WORK_PHONE
,SERV_PROV_ZIP_POSTAL_CODE
-- ,SHIFT
-- ,SKILL
,STATUS
,SUBREGION
-- ,TRADE
,VENDOR_ID
,VENDOR_PURCHASING_FAX
,VENDOR_SITECODE
,VENDOR_TICKET
,VENDOR_COMPANYNAME
,VIP
,WORK_ORDER_NO
,WORK_REQUEST
,WORK_REQUEST_CLASS
,WORK_TYPE
-- ,WR_COST
,WR_DESCRIPTION
-- ,WR_DISPATCH_METHOD
,WR_STATUS
,COUNTRY
,CREATE_DATE
VALUES
(SELECT DISTINCT
JT.JT_ID AS JT_ID
,NVL((ROUND((JT_DATE_COMPLETED - JT_DATE_REQUESTED) * 24,2)),0) AS ACTUAL_HRS_TO_COMPLETE
,NVL((ROUND((JT_DATE_RESPONDED - JT_DATE_REQUESTED) * 24,2)),0) AS ACTUAL_HRS_TO_RESPOND
,PEO1.PEO_NAME AS AGENT_NAME
,PEO1.PEO_USER_NAME AS ASAGENT_SOE_ID
,LE.LGLENT_DESC AS AP_SYSTEM
-- ,' ' AS ASSIGN_WORK_REQUEST_COMMENT
,DECODE(JT.JT_BILL_ID,138802,'CLIENT BILLABLE'
,138803,'CONTRACTED'
,138804,'INTERNAL BILLABLE',NULL,' ') AS BILLABLE
,BL.BLDG_NAME_CC AS BUILDING
,BL.BLDG_ID_LS AS BUILDING_ID
,DECODE(BL.BLDG_ACTIVE_CC, 'Y', 'ACTIVE', 'INACTIVE') AS BUILDING_STATUS
,DECODE(JT.JT_WRK_CAUSE_ID,141521,'STANDARD WEAR AND TEAR'
,141522,'NEGLIGENCE'
,141523,'ACCIDENTAL'
,141524,'MECHANICAL MALFUNCTION'
,141525,'OVERSIGHT'
,141526,'VANDAL'
,141527,'STANDARD'
,141528,'PROJECT WORK'
,6058229,'TEST',NULL,' ') AS CAUSE_TYPE
-- ,' ' AS COMMENTS
,PEO3.PEO_NAME AS COMPLETED_BY
,JT.JT_REQUESTOR_EMAIL AS CONTACT_EMAIL
,JT.JT_REQUESTOR_NAME_FIRST || ' ' ||JT.JT_REQUESTOR_NAME_LAST AS CONTACT_NAME
,JT.JT_REQUESTOR_PHONE AS CONTACT_PHONE
,CC.CSTCTRCD_APCODE AS CORP_CODE
,CC.CSTCTRCD_CODE AS COST_CENTER
,JT.JT_DATE_CLOSED AS DATE_CLOSED
,JT.JT_DATE_COMPLETED AS DATE_COMPLETED
,JT.JT_DATE_REQUESTED AS DATE_REQUESTED
,JT.JT_DATE_RESPONDED AS DATE_RESPONDED
,JT.JT_DATE_RESPONSE_ECD AS DATE_RESPONSE_ECD
,JT.JT_DATE_SCHEDULED AS DATE_SCHEDULED
,DECODE(JT.JT_DEF_ID,139949,'WTG VENDOR RESPONSE'
,139950,'WAITING ON PARTS'
,139951,'LABOR AVAILABILITY'
,139952,'DEFERRED- HI PRI WORK'
,139953,'WTG APPROVAL'
,139954,'FUNDING REQUIRED'
,139955,'ACCESS DENIED'
,139956,'WTG MATERIAL',NULL,' ') AS DEFERRAL_REASON
,JT.JT_DESCRIPTION AS DESCRIPTION
,JT.JT_DATE_RESCHED_ECD AS ECD
,FMG.FACILITY_MANAGER AS FACILITY_MANAGER
,FL.FLOORS_TEXT AS FLOOR
,GL.GENLED_DESC AS GENERAL_LEDGER
-- ,' ' AS KIOSK_DATE_REQUESTED
-- ,' ' AS KIOSK_DISPATCH_CONFIRMED
-- ,' ' AS KIOSK_DISPATCHED
,EQP.EQUIP_CUSTOMER_CODE AS LINKED_EQUIPMENT_ALIAS
,EQP.EQUIP_ID AS LINKED_EQUIPMENT_ID
,EQP.EQUIP_TEXT AS LINKED_EQUIPMENT_NAME
,DECODE(JT_ORIGINATOR_TYPE_ID,1000,'PROJECT MOVE REQUEST'
,138834,'CUSTOMER INITIATED CORRECTION'
,138835,'CUSTOMER INITIATED REQUEST'
,138836,'CORRECTIVE MAINTENANCE'
,138837,'CONFERENCE ROOM BOOKING'
,138838,'PROJECT INITIATED REQUEST'
,138839,'PLANNED PREVENTIVE MAINTENANCE'
,138840,'SELF INITATED REQUEST',NULL,' ') AS ORIGINATOR_TYPE
-- ,' ' AS PAYMENT_TERMS
,PRIORITY_TEXT AS PRIORITY_CODE
,SWOTY.SWORKTYPE_TEXT AS PROBLEM_TYPE
,PROP.PROPERTY_NAME_CC AS PROPERTY
,JT.JT_COST_QUOTE_TOTAL AS QUOTE_TOTAL
,PAR.LEVELS_NAME AS REGION
,DECODE(JT.JT_REPDEF_ID,141534,'ADJUSTED SETTING'
,141535,'TRAINING FOR END'
,141536,'NEW REQUEST'
,141537,'NO REPAIR REQUIR'
,141538,'REPLACED PARTS'
,141539,'REPLACE EQUIPMEN'
,1000699,'NEW REQUEST',NULL,' ') AS REPAIR_DEFINITIONS
,JT.JT_REPAIRDESC AS REPAIR_DESCRIPTION
,JT.JT_REQUESTOR AS REQUESTOR
-- ,' ' AS REQUESTOR_COST_CENTER
,JT.JT_REQUESTOR_EMAIL AS REQUESTOR_EMAIL
,JT.JT_REQUESTOR_NAME_FIRST AS REQUESTOR_NAME
,JT.JT_REQUESTOR_PHONE AS REQUESTOR_PHONE
-- ,' ' AS RESPONSE_TIME
,RM.ROOM_NAME_CC AS ROOM
,P1.PEO_PROVIDER_CODE1 AS SERVICE_PROVIDER
,P1.PEO_ADDRESS_1 AS SERVICE_PROVIDER_ADDRESS
,PEOCITY.CITY_TEXT SERVICE_PROVIDER_CITY
,P1.PEO_PROVIDER_CODE1 AS SERVICE_PROVIDER_CODE
,PEOCITY.CITY_COUNTRY_NAME AS SERVICE_PROVIDER_COUNTRY
,PEOCUR.CURRENCY_TEXT AS SERVICE_PROVIDER_CURRENCY
,P1.PEO_NAME AS SERVICE_PROVIDER_DESCRIPTION
,P1.PEO_DISPATCH_METHOD AS SERV_PROV_DISPATC_HMETHOD
,P1.PEO_RATE_DOUBLE AS SERV_PROV_DOUBLE_TIME_RATE
,P1.PEO_EMAIL AS SERVICE_PROVIDER_EMAIL
,P1.PEO_EMERGENCY_PHONE AS SERV_PROV_EMERGENCY_PHONE
,P1.PEO_FAX AS SERVICE_PROVIDER_FAX_NUMBER
,P1.PEO_HOME_PHONE AS SERVICE_PROVIDER_HOME_PHONE
,P1.PEO_RATE_HOURLY AS SERVICE_PROVIDER_HOURLY_RATE
,P1.PEO_TITLE AS SERVICE_PROVIDER_JOB_TITLE
,P1.PEO_METHOD_ID AS SERVICE_PROVIDER_METHOD
,P1.PEO_CELL_PHONE AS SERVICE_PROVIDER_MOBILE_PHONE
,P1.PEO_PAGER AS SERVICE_PROVIDER_PAGER
,P1.PEO_RATE_DIFFERENTIAL AS SERVICE_PROVIDER_RATES
,P1.PEO_RATE_DIFFERENTIAL AS SER_PROV_SHIFT_DIFFERENTIAL
,PEOCITY.CITY_STATE_PROV_TEXT AS SERV_PROV_STATE_PROVINCE
,DECODE(P1.PEO_ACTIVE, 'Y', 'ACTIVE', 'INACTIVE') AS SERVICE_PROVIDER_STATUS
,P1.PEO_URL AS SERV_PROV_WEB_SITE_ADDRESS
,P1.PEO_PHONE AS SERVICE_PROVIDER_WORK_PHONE
,P1.PEO_POSTAL_CODE AS SERV_PROV_ZIP_POSTAL_CODE
-- ,' ' AS SHIFT
-- ,' ' AS SKILL
,DECODE(JT.JT_BIGSTATUS_ID,138813,'NEW'
,138814,'PENDING'
,138815,'OPEN'
,138816,'COMPLETED'
,138817,'CLOSED'
,138818,'CANCELLED',NULL,' ') AS STATUS
,LEV.LEVELS_NAME AS SUBREGION
-- ,' ' AS TRADE
,P1.PEO_LS_INTERFACE_CODE1 AS VENDOR_ID
,P1.PEO_FAX AS VENDOR_PURCHASING_FAX
,P1.PEO_VENDOR_SITE_CODE AS VENDOR_SITECODE
,JT.JT_ID AS VENDOR_TICKET
,P1.PEO_NAME AS VENDOR_COMPANYNAME
,JT.JT_REQUESTOR_VIP AS VIP
,WO.WO_ID AS WORK_ORDER_NO
,JT.JT_ID AS WORK_REQUEST
,JT.JT_CLASS_ID AS WORK_REQUEST_CLASS
,WOTY.WORKTYPE_TEXT AS WORK_TYPE
-- ,' ' AS WR_COST
,JT.JT_DESCRIPTION AS WR_DESCRIPTION
-- ,' ' AS WR_DISPATCH_METHOD
,DECODE(JT.JT_BIGSTATUS_ID,138813,'NEW'
,138814,'PENDING'
,138815,'OPEN'
,138816,'COMPLETED'
,138817,'CLOSED'
,138818,'CANCELLED',NULL,' ') AS WR_STATUS
,CTRY.COUNTRY_NAME AS COUNTRY
,SYSDATE --LD_CURR_TIME
FROM CITI.JOBTICKET JT,
CITI.PROPERTY PROP,
CITI.BLDG BL,
CITI.BLDG_LEVELS BLDGLVL,
CITI.LEVELS LEV,
CITI.LEVELS PAR,
(SELECT CRSTOOLS.STRAGG(PEO_NAME) FACILITY_MANAGER,
BLDGCON_BLDG_ID
FROM CITI.BLDG_CONTACTS, CITI.PEOPLE
WHERE BLDGCON_PEO_ID = PEO_ID
AND BLDGCON_CONTYPE_ID IN (40181, 10142)
GROUP BY BLDGCON_BLDG_ID) FMG,
CITI.FLOORS FL,
CITI.ROOM RM,
CITI.GENERAL_LEDGER GL,
CITI.LEGAL_ENTITY LE,
CITI.COST_CENTER_CODES CC,
CITI.EQUIPMENT EQP,
CITI.WORKTYPE WOTY,
CITI.SUBWORKTYPE SWOTY,
CITI.WORK_ORDER WO,
CITI.JT_WORKERS JTWO,
CITI.PRIORITY,
CITI.COUNTRY CTRY,
CITI.PEOPLE P1,
CITI.PEOPLE PEO3,
CITI.PEOPLE PEO1,
CITI.CITY PEOCITY,
CITI.CURRENCY PEOCUR
WHERE JT.JT_BLDG_ID = BL.BLDG_ID
AND BL.BLDG_ID = BLDGLVL.BLDG_LEVELS_BLDG_ID
AND BLDGLVL.BLDG_LEVELS_LEVELS_ID = LEV.LEVELS_ID
AND LEV.LEVELS_PARENT = PAR.LEVELS_ID(+)
AND PROP.PROPERTY_ID = BL.BLDG_PROPERTY_ID
AND BL.BLDG_ACTIVE_LS = 'N'
AND JT.JT_FLOORS_ID = FL.FLOORS_ID(+)
AND JT.JT_ROOM_ID = RM.ROOM_ID(+)
AND JT.JT_BLDG_ID = FMG.BLDGCON_BLDG_ID(+)
AND JT.JT_GENLED_ID = GL.GENLED_ID(+)
AND GL.GENLED_LGLENT_ID = LE.LGLENT_ID(+)
AND JT.JT_CSTCTRCD_ID = CC.CSTCTRCD_ID(+)
AND JT.JT_EQUIP_ID = EQP.EQUIP_ID(+)
AND JT.JT_ID = JTWO.JTW_JT_ID(+)
AND JT.JT_WORKTYPE_ID = WOTY.WORKTYPE_ID(+)
AND JT.JT_SWORKTYPE_ID = SWOTY.SWORKTYPE_ID(+)
AND JT.JT_WO_ID = WO.WO_ID
AND JT.JT_PRIORITY_ID = PRIORITY_ID(+)
--AND jt.jt_date_requested >= ADD_MONTHS (SYSDATE, -12)
AND JT.JT_LAST_UPDATE >= ADD_MONTHS(LD_CURR_TIME, -12)
AND BL.BLDG_COUNTRY_ID = CTRY.COUNTRY_ID
AND JTWO.JTW_PEO_ID = P1.PEO_ID(+)
AND P1.PEO_CITY_ID = PEOCITY.CITY_ID(+)
AND JT.JT_COMPLETED_BY_PEO_ID = PEO3.PEO_ID(+)
AND P1.PEO_RATE_CURRENCY_ID = PEOCUR.CURRENCY_ID(+)
AND JT.JT_AGENT_PEO_ID = PEO1.PEO_ID(+)
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('SQLCODE :' || SQLCODE || ' Error :' || SQLERRM);
END WORK_KIOSK_FULL;Here's the link for infor on the [Oracle Direct-Path INSERT |http://download.oracle.com/docs/cd/B10501_01/server.920/a96524/c21dlins.htm#10778].
Also, if you are truly intent on using a CURSOR FOR LOOP with the BULK COLLECT, I suggest you read Steven Feuerstein's article [PL/SQL Practices: On BULK COLLECT |http://www.oracle.com/technology/oramag/oracle/08-mar/o28plsql.html].
Hope this helps.
Craig...
If my response or the response of another was helpful, please mark it accordingly
Maybe you are looking for
-
Doubt in java.util.logging
Hi, I have doubt in logging api provided in java 1.4. I have a simple program to get the logger and output log into it. This is how the program looks. LogTest.java import java.util.logging.*; import java.util.*; public class LogTest { public static v
-
Why can't I change the screen orientation of my iPad?
I just upgraded my iPad to IOS 7.0.4. Suddenly it seems to be locked in portrait mode. I have tried turning the lock feature off and on, but that doesn't help. I am at a loss.
-
Hi Running 10g db - can enqueue and dequeue at db level. A client java application need to subscribe to a queue. I've got (taken from the server) classes12.jar,nls_charset12.jar, classes12dms.jar in path. Had a look into classes12dms.jar and it seems
-
Creating video transitions on completion
Hi there I'm creating an Interactive DVD with many speakers and videos. Each presentation is up to an hour long and has been cut up into it's chapters. I'm using a combo box to select the chapters by creating an action sequence, and on select changin
-
Error 14 on iPhone 5 wont restore
I was trying to factory restore my iPhone 5 in intunes and its now stuck in dfu mod suggestions ?