Bulk collect update error
Re: ORA 06550 in FOR ALL INSERT...Please help me ..
DECLARE
CURSOR c1 IS SELECT fs.user_id, fs.lot_id, ts.ml_ac_no, ts.td_prs_dt, ts.unit_cost, ts.cost_basis
FROM tb_xop_sharelot_fraction_snap fs, tb_xop_sharelot ts
WHERE fs.lot_id=ts.lot_id AND fs.user_id=ts.user_id;
Type ty_tab1 is table of C1%rowtype index by PLS_INTEGER;
ltab1 ty_tab1;
BEGIN
OPEN C1;
LOOP
FETCH C1 BULK COLLECT INTO ltab1 LIMIT 5000;
LOOP
FORALL i in ltab1.first ..ltab1.last
Update tb_xop_sharelot_fraction_snap
set ml_ac_no=ltab1(i).ml_ac_no
,td_prs_dt=ltab1(i).td_prs_dt
,unit_cost=ltab1(i).unit_cost
,cost_basis=ltab1(i).cost_basis;
commit;
END LOOP;
EXIT WHEN C1%NOTFOUND;
END LOOP;
CLOSE C1;
DBMS_OUTPUT.PUT_LINE('ml_ac_no, td_prs_dt, unit_cost and cost_basis columns are updated successfully:'||ltab1.count);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLCODE|| ' ' ||SQLERRM);
END;
{ORA-06550: line 21, column 37:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
ORA-06550: line 21, column 37:
PLS-00382: expression is of wrong type
ORA-06550: line 20, column 36:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
ORA-06550: line 20, column 36:
PLS-00382: expression is of wrong type
ORA-06550: line 19, column 56:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
ORA-06550: line 19, column 56:
PLS-00382: expression is of wrong type
ORA-06550: line 18, column 46:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
ORA-06550: line 18, column 46:
PLS-00382: expression is of wrong type
ORA-06550: line 21, column 37:
PL/SQL: ORA-22806: not an object or REF
ORA-06550: line 17, column 16:
PL/SQL: SQL Statement ignored
{Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi this version}
Hoek wrote:
Some more detail: http://www.oracle-developer.net/display.php?id=410
Creating object type + using treat seems like an overkill to simply creating individual collections:
SQL> declare
2 cursor v_cur is select empno,ename,sal from emp where deptno = 10;
3 type v_tbl_type is table of v_cur%rowtype index by pls_integer;
4 v_tbl v_tbl_type;
5 begin
6 select empno,ename,sal
7 bulk collect
8 into v_tbl
9 from emp
10 where deptno = 10;
11 forall i in 1..v_tbl.count
12 update tbl
13 set name = v_tbl(i).ename,
14 sal = v_tbl(i).sal;
15 end;
16 /
sal = v_tbl(i).sal;
ERROR at line 14:
ORA-06550: line 14, column 19:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND
table of records
ORA-06550: line 14, column 19:
PLS-00382: expression is of wrong type
ORA-06550: line 13, column 20:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND
table of records
ORA-06550: line 13, column 20:
PLS-00382: expression is of wrong type
ORA-06550: line 14, column 19:
PL/SQL: ORA-22806: not an object or REF
ORA-06550: line 12, column 7:
PL/SQL: SQL Statement ignored
SQL> declare
2 cursor v_cur is select empno,ename,sal from emp where deptno = 10;
3 v_empno_tbl sys.OdciNumberList;
4 v_ename_tbl sys.OdciVarchar2List;
5 v_sal_tbl sys.OdciNumberList;
6 begin
7 select empno,ename,sal
8 bulk collect
9 into v_empno_tbl,v_ename_tbl,v_sal_tbl
10 from emp
11 where deptno = 10;
12 forall i in 1..v_empno_tbl.count
13 update tbl
14 set name = v_ename_tbl(i),
15 sal = v_sal_tbl(i);
16 end;
17 /
PL/SQL procedure successfully completed.
SQL> SY.
Similar Messages
-
Bulk collect & forall error in script
hi,
i am having senerio as below in my code.but i am getting error "too many values for emp1". i know why i m getting error but i need to insert emp column " EMPNO, ENAME" value in emp1 table &
emp column " EMPNO, ENAME,sal" value in emp2 table .
how to do it.sud i declare 2 diffrent cursor ? 1 cursor having only "EMPNO, ENAME" & 2nd having "EMPNO, ENAME, SAL" values.
or any other best way to do this. plz help ..
DECLARE
CURSOR s_cur1
IS SELECT EMPNO, ENAME, SAL
FROM EMP E;
TYPE fetch_array1 IS TABLE OF s_cur1%ROWTYPE;
s_array1 fetch_array1;
BEGIN
OPEN s_cur1;
LOOP
FETCH s_cur1 BULK COLLECT INTO s_array1 LIMIT 1000;
FORALL i IN 1..s_array1.COUNT SAVE EXCEPTIONS
INSERT INTO EMP1 --(EMPNO, ENAME)
VALUES s_array1(i);
FORALL i IN 1..s_array1.COUNT SAVE EXCEPTIONS
INSERT INTO EMP2 --(EMPNO, ENAME, sal)
VALUES s_array1(i);
EXIT WHEN s_cur1%NOTFOUND;
END LOOP;
CLOSE s_cur1;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Unexpected Error:'||SqleRrm);
END;
table structures:-
CREATE TABLE EMP (
EMPNO NUMBER,
ENAME VARCHAR2 (100),
SAL NUMBER ) ;
CREATE TABLE EMP1 (
EMPNO NUMBER,
ENAME VARCHAR2 (100),
CREATE TABLE EMP2 (
EMPNO NUMBER,
ENAME VARCHAR2 (100),
SAL NUMBER ) ;
---------------------------------------------------------------------Do it in one simple SQL.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> desc emp
Name Null? Type
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
SQL> desc emp1
Name Null? Type
EMPNO NUMBER
ENAME VARCHAR2(100)
SQL> desc emp2
Name Null? Type
EMPNO NUMBER
ENAME VARCHAR2(100)
SAL NUMBER
SQL> INSERT ALL WHEN 1 = 1 THEN INTO emp1
2 (empno, ename)
3 VALUES
4 (empno, ename) WHEN 2 = 2 THEN INTO emp2
5 (empno, ename, sal)
6 VALUES
7 (empno, ename, sal)
8 SELECT empno, ename, sal FROM emp;
28 rows created.
SQL> SELECT COUNT(*) FROM emp1;
COUNT(*)
14
SQL> SELECT COUNT(*) FROM emp2;
COUNT(*)
14
SQL> SELECT COUNT(*) FROM emp;
COUNT(*)
14
SQL> -
Retruning bulk collect into---Error
the code:
DECLARE
v_file UTL_FILE.file_type;
TYPE emp_tab_type IS TABLE OF emp%ROWTYPE;
v_row VARCHAR2 (100);
emp_tab emp_tab_type;
BEGIN
v_file := UTL_FILE.fopen ('XML_DIR', 'emp.txt', 'w');
EXECUTE IMMEDIATE 'select * from emp'
RETURNING BULK COLLECT INTO emp_tab;
FOR i IN emp_tab.FIRST .. emp_tab.LAST
LOOP
v_row :=
emp_tab.empno
|| ','
|| emp_tab.ename
|| ','
|| emp_tab.job
|| ','
|| emp_tab.mgr
|| ','
|| emp_tab.hiredate
|| ','
|| emp_tab.sal
|| ','
|| emp_tab.comm
|| ','
|| emp_tab.deptno;
UTL_FILE.put_line (v_file, v_row, TRUE);
END LOOP;
UTL_FILE.fclose (v_file);
EXCEPTION
WHEN OTHERS
THEN
UTL_FILE.fclose (v_file);
END;
the error:
ORA-06550: line 12, column 7:
PLS-00429: unsupported feature with RETURNING clause
please help!Couple of errors:
1) There is absolutely no need to use dynamic SQL here, so get rid of the EXECUTE IMMEDIATE.
2) If any error occurs, then you are hiding it from the caller by your WHEN OTHERS THEN exception handler. Just get rid of it, or use WHEN OTHERS THEN UTL_FILE.fclose (v_file); RAISE; END;
3) You have to refer to the elements of your nested table emp_tab and not to the nested table itself, so add a "(i)" to refer to the element inside the loop.
Example:
SQL> DECLARE
2 TYPE emp_tab_type IS TABLE OF emp%ROWTYPE;
3 v_row VARCHAR2 (100);
4 emp_tab emp_tab_type;
5 BEGIN
6 select *
7 BULK COLLECT INTO emp_tab
8 from emp
9 ;
10 FOR i IN emp_tab.FIRST .. emp_tab.LAST
11 LOOP
12 v_row :=
13 emp_tab(i).empno || ',' ||
14 emp_tab(i).ename || ',' ||
15 emp_tab(i).job || ',' ||
16 emp_tab(i).mgr || ',' ||
17 emp_tab(i).hiredate || ',' ||
18 emp_tab(i).sal || ',' ||
19 emp_tab(i).comm || ',' ||
20 emp_tab(i).deptno
21 ;
22 dbms_output.put_line(v_row);
23 END LOOP;
24 END;
25 /
7369,SMITH,CLERK,7902,17-12-1980 00:00:00,800,,20
7499,ALLEN,SALESMAN,7698,20-02-1981 00:00:00,1600,300,30
7521,WARD,SALESMAN,7698,22-02-1981 00:00:00,1250,500,30
7566,JONES,MANAGER,7839,02-04-1981 00:00:00,2975,,20
7654,MARTIN,SALESMAN,7698,28-09-1981 00:00:00,1250,1400,30
7698,BLAKE,MANAGER,7839,01-05-1981 00:00:00,2850,,30
7782,CLARK,MANAGER,7839,09-06-1981 00:00:00,2450,,10
7788,SCOTT,ANALYST,7566,09-12-1982 00:00:00,3000,,20
7839,KING,PRESIDENT,,17-11-1981 00:00:00,5000,,10
7844,TURNER,SALESMAN,7698,08-09-1981 00:00:00,1500,0,30
7876,ADAMS,CLERK,7788,12-01-1983 00:00:00,1100,,20
7900,JAMES,CLERK,7698,03-12-1981 00:00:00,950,,30
7902,FORD,ANALYST,7566,03-12-1981 00:00:00,3000,,20
7934,MILLER,CLERK,7782,23-01-1982 00:00:00,1300,,10
PL/SQL procedure successfully completed.Regards,
Rob. -
How can I see error when execute UPDATE with BULK COLLECT
Hi
I have a code
CURSOR c_renov_eleg IS
SELECT t2.ROWID
FROM mytable t2
WHERE BLA BLA BLA
OPEN c_renov_eleg;
LOOP
FETCH c_renov_eleg BULK COLLECT
INTO w_rowid LIMIT 1000;
FORALL i IN 1 .. w_rowid.COUNT
UPDATE mytable
SET id_baixa_elegibilidade = K_SCNOB_BXA_RENOVACAO,
column01 = arr_ciclo(1),
dt_ultima_atualizacao = SYSDATE,
cd_usuario_atualizacao = USER
WHERE ROWID = w_rowid(i);
COMMIT;
EXIT WHEN c_renov_eleg%NOTFOUND;
END LOOP;How can I to sse when and where have some error ? , in Exception return what record ?How can I to sse when and where have some error
?Have a look at
[url=http://download.oracle.com/docs/cd/B28359_01/appd
ev.111/b28370/tuning.htm#i49099]Handling FORALL
Exceptions (%BULK_EXCEPTIONS Attribute).btw. just never ever commit in a for loop ;)
(Tubby is just too fast ;))
Hi , thank all
btw. just never ever commit in a for loopWhen I must to COMMIT using BULK COLLECT ? -
Error while using bulk collect
Hi
I tried with the following code,
DECLARE
TYPE EmpRec IS RECORD (last_name EMP.ename%TYPE,
salary emp.sal%TYPE);
emp_info EmpRec;
TYPE empnest IS TABLE OF EMP.empno%TYPE;
empnestvar empnest;
BEGIN
empnestvar := empnest(7566,7788);
FOR i in empnestvar.first..empnestvar.last LOOP
UPDATE emp SET sal = sal * 1.1 WHERE empno = empnestvar(i)
RETURNING ename, sal BULK COLLECT INTO emp_info;
DBMS_OUTPUT.PUT_LINE('Just gave a raise to ' || emp_info.last_name ||
', who now makes ' || emp_info.salary);
ROLLBACK;
END LOOP;
END;getting this following err
RETURNING ename, sal BULK COLLECT INTO emp_info;
ERROR at line 11:
ORA-03113: end-of-file on communication channelCould you please advice me in this
ThanksThe main problem i you are bulk collecting into a "record" type variable.
SQL>
SQL> SHOW user
USER is "SCOTT"
SQL> SELECT * FROM v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Prod
PL/SQL Release 10.2.0.2.0 - Production
CORE 10.2.0.2.0 Production
TNS for Solaris: Version 10.2.0.2.0 - Production
NLSRTL Version 10.2.0.2.0 - Production
SQL> SET SERVEROUT on
SQL> DECLARE
TYPE EmpRec IS RECORD(
last_name EMP.ename%TYPE,
salary emp.sal%TYPE);
TYPE emp_bl IS TABLE OF EmpRec; --Added.
emp_info emp_bl; --Changed.
TYPE empnest IS TABLE OF EMP.empno%TYPE;
empnestvar empnest;
BEGIN
empnestvar := empnest(7566, 7788);
FOR i in empnestvar.first .. empnestvar.last LOOP
UPDATE emp
SET sal = sal * 1.1
WHERE empno = empnestvar(i) RETURNING ename, sal BULK COLLECT INTO
emp_info;
DBMS_OUTPUT.PUT_LINE('Just gave a raise to ' || emp_info(1)
.last_name || ', who now makes ' || emp_info(1)
.salary);
ROLLBACK;
END LOOP;
END; 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
22 /
Just gave a raise to JONES, who now makes 3272.5
Just gave a raise to SCOTT, who now makes 3300
PL/SQL procedure successfully completed.
SQL>Although, I must say that, as because empno is the primary key, here RETURNING INT with BULK COLLECT doesn't make any sense. -
Need help with Bulk Collect ForAll Update
Hi - I'm trying to do a Bulk Collect/ForAll Update but am having issues.
My declarations look like this:
CURSOR cur_hhlds_for_update is
SELECT hsh.household_id, hsh.special_handling_type_id
FROM compas.household_special_handling hsh
, scr_id_lookup s
WHERE hsh.household_id = s.id
AND s.scr = v_scr
AND s.run_date = TRUNC (SYSDATE)
AND effective_date IS NULL
AND special_handling_type_id = 1
AND created_by != v_user;
TYPE rec_hhlds_for_update IS RECORD (
household_id HOUSEHOLD_SPECIAL_HANDLING.household_id%type,
spec_handl_type_id HOUSEHOLD_SPECIAL_HANDLING.SPECIAL_HANDLING_TYPE_ID%type
TYPE spec_handling_update_array IS TABLE OF rec_hhlds_for_update;
l_spec_handling_update_array spec_handling_update_array;And then the Bulk Collect/ForAll looks like this:
OPEN cur_hhlds_for_update;
LOOP
FETCH cur_hhlds_for_update BULK COLLECT INTO l_spec_handling_update_array LIMIT 1000;
EXIT WHEN l_spec_handling_update_array.count = 0;
FORALL i IN 1..l_spec_handling_update_array.COUNT
UPDATE compas.household_special_handling
SET effective_date = TRUNC(SYSDATE)
, last_modified_by = v_user
, last_modified_date = SYSDATE
WHERE household_id = l_spec_handling_update_array(i).household_id
AND special_handling_type_id = l_spec_handling_update_array(i).spec_handl_type_id;
l_special_handling_update_cnt := l_special_handling_update_cnt + SQL%ROWCOUNT;
END LOOP;And this is the error I'm receiving:
ORA-06550: line 262, column 31:
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
ORA-06550: line 262, column 31:
PLS-00382: expression is of wrong type
ORA-06550: line 263, column 43:
PL/SQL: ORA-22806: not an object or REF
ORA-06550: line 258, column 9:
PL/SQL: SQMy problem is that the table being updated has a composite primary key so I have two conditions in my where clause. This the the first time I'm even attempting the Bulk Collect/ForAll Update and it seems like it would be straight forward if I was only dealing with a single-column primary key. Can anyone please help advise me as to what I'm missing here or how I can accomplish this?
Thanks!
ChristineYou cannot reference a column inside a record when doin a for all. You need to refer as a whole collection . So you will need two collections.
Try like this,
DECLARE
CURSOR cur_hhlds_for_update
IS
SELECT hsh.household_id, hsh.special_handling_type_id
FROM compas.household_special_handling hsh, scr_id_lookup s
WHERE hsh.household_id = s.ID
AND s.scr = v_scr
AND s.run_date = TRUNC (SYSDATE)
AND effective_date IS NULL
AND special_handling_type_id = 1
AND created_by != v_user;
TYPE arr_household_id IS TABLE OF HOUSEHOLD_SPECIAL_HANDLING.household_id%TYPE
INDEX BY BINARY_INTEGER;
TYPE arr_spec_handl_type_id IS TABLE OF HOUSEHOLD_SPECIAL_HANDLING.SPECIAL_HANDLING_TYPE_ID%TYPE
INDEX BY BINARY_INTEGER;
l_household_id_col arr_household_id;
l_spec_handl_type_id_col arr_spec_handl_type_id;
BEGIN
OPEN cur_hhlds_for_update;
LOOP
FETCH cur_hhlds_for_update
BULK COLLECT INTO l_household_id_col, l_spec_handl_type_id_col
LIMIT 1000;
EXIT WHEN cur_hhlds_for_update%NOTFOUND;
FORALL i IN l_household_id_col.FIRST .. l_household_id_col.LAST
UPDATE compas.household_special_handling
SET effective_date = TRUNC (SYSDATE),
last_modified_by = v_user,
last_modified_date = SYSDATE
WHERE household_id = l_household_id_col(i)
AND special_handling_type_id = l_spec_handl_type_id_col(i);
--l_special_handling_update_cnt := l_special_handling_update_cnt + SQL%ROWCOUNT; -- Not sure what this does.
END LOOP;
END;G. -
How to view errors if bulk collect has thrown errors
Hi,
I have few questions.
1.How to view error whether bulk collect is successful or not
2.What is identified & unidentified relationships in ERWIN
3.How to see the errors whether the sql loder is successful or not
and how to open the log file.Is there any specific command in UNIX
which tells loader is successful or thrown error
4.When executing the pl/sql procedure from UNIX.how to check for errors.
Please provide the answers for this
ThanksUse SAVE EXCEPTIONS clause in your FORALL loop.
Is this for homework/test? -
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 -
Error while doing Bulk Collect to a table type
I'm using a Table type to accumulate resultset from a loop and finally return the records in the table type as a ref cursor to the front end.
But when I'm using Bult collect to insert into the table type object it keeps throwing an error
'PLS-00597: expression 'TAB_CALENDAR_AVAIL_RESULTSET' in the INTO list is of wrong type'. Can someone help me to let me know what could be the reason for this error. I'm not able to proceed further, please help.
Here is the code.
CREATE OR REPLACE PACKAGE hotel
AS
TYPE calendar_cursor IS REF CURSOR;
TYPE type_calendar_avail is RECORD(
HOTEL_ID AVAILABILITY_CALENDAR.hotel_id%TYPE,--varchar2(4), --AVAILABILITY_CALENDAR.hotel_id%TYPE,
AVAIL_DATE AVAILABILITY_CALENDAR.AVAIL_DATE%TYPE ,
TOTAL_COUNT number
TYPE type_calendar_avail_resultset IS TABLE OF type_calendar_avail;
tab_calendar_avail_resultset type_calendar_avail_resultset ; -- declare variable of type type_calendar_avail_resultset
PROCEDURE sp_get_calendar_results (
sallhotelswithavaildate VARCHAR2,
ilengthofstay NUMBER,
sorcowner VARCHAR2,
all_unittypes VARCHAR2, --DBMS_SQL.VARCHAR2S
calendar_resultset OUT calendar_cursor
-- tab_calendar_avail_resultset out type_calendar_avail_resultset
PROCEDURE sp_get_calendar_results (
sallhotelswithavaildate VARCHAR2,
ilengthofstay NUMBER,
-- ivariant NUMBER,
sorcowner VARCHAR2,
all_unittypes VARCHAR2, --DBMS_SQL.VARCHAR2S
calendar_resultset OUT calendar_cursor
AS
sbuf VARCHAR2 (200);
sepr VARCHAR2 (1);
shotelwithdate VARCHAR2 (200);
shotelid VARCHAR2 (10);
savaildate VARCHAR2 (8);
sactualavaildate VARCHAR2 (8);
pos NUMBER;
istart NUMBER;
sstartdate VARCHAR2 (8);
senddate VARCHAR2 (8);
squery VARCHAR2 (32767) := '';
sunittypecond VARCHAR2 (500) := '';
sunitdesccond VARCHAR2 (500) := '';
v_unit_cond a_unit_cond;
tempunitcond VARCHAR2 (50) := '';
BEGIN
istart := 1;
LOOP
tempunitcond := hotel.stringtokenizer (all_unittypes, istart, '|');
IF tempunitcond IS NOT NULL
THEN
v_unit_cond (istart) := tempunitcond;
istart := istart + 1;
END IF;
EXIT WHEN tempunitcond IS NULL;
END LOOP;
sunitdesccond := hotel.get_unit_description_cond (v_unit_cond);
DBMS_OUTPUT.put_line ('unit description : ' || sunitdesccond);
sbuf := sallhotelswithavaildate;
sepr := '|';
istart := 1;
LOOP
shotelwithdate := hotel.stringtokenizer (sbuf, istart, sepr);
EXIT WHEN shotelwithdate IS NULL;
shotelid :=
SUBSTR (shotelwithdate, 1, INSTR (shotelwithdate, ',') - 1);
savaildate :=
SUBSTR (shotelwithdate, INSTR (shotelwithdate, ',') + 1);
squery :=
' SELECT MIN (ad.avail_date) '
|| ' FROM wvo_fonres.fpavail_daily ad'
|| ' WHERE ad.hotel_id = '
|| shotelid
|| ' AND ad.days_left >= '
|| ilengthofstay
|| ' AND ad.avail_date >= '
|| savaildate;
IF UPPER (sorcowner) = 'N'
THEN
squery :=
squery
|| ' AND ad.ORC_TYPE != ''R'' and ad.ORC_TYPE != ''P'' and ad.ORC_TYPE != ''E'' ';
END IF;
squery := squery || ' AND ( ' || sunitdesccond || ') ';
EXECUTE IMMEDIATE squery
INTO sactualavaildate;
DBMS_OUTPUT.put_line ('Actual available Date: ' || sactualavaildate);
hotel.sp_get_startdate_enddate (sactualavaildate,
--ivariant,
sstartdate,
senddate
sunittypecond := hotel.get_unittype_cond (v_unit_cond, sorcowner);
-- execute immediate
squery :=
'select HOTEL_ID, AVAIL_DATE, ' || sunittypecond || ' AS TOTAL_COUNT '
|| ' FROM AVAILABILITY_CALENDAR A '
|| 'WHERE '
|| 'AVAIL_DATE >= '''
|| sstartdate
|| ''' '
|| 'AND '
|| 'AVAIL_DATE <= '''
|| senddate
|| ''' '
||'AND '
|| 'A.HOTEL_ID IN ('
|| shotelid
|| ') '
|| 'AND ('
|| sunittypecond
|| '> 0) '
|| -- where total available count of unit type is greater than 0
' ORDER BY AVAIL_DATE'; --order clause
open calendar_resultset for squery;
fetch calendar_resultset BULK COLLECT INTO tab_calendar_avail_resultset;
istart := istart + 1;
END LOOP;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line
(SQLERRM (SQLCODE));
RAISE;
END sp_get_calendar_results;
END hotel;
/1. put tags [co[/b][b]de] and [co[/b][b]de] around your code, so it's readable
B. what does "hotel.get_unittype_cond (v_unit_cond, sorcowner)" actually retun?
and third, try this for the array declaration:
tab_calendar_avail_resultset type_calendar_avail_resultset := type_calendar_avail_resultset ; () ; -
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. -
Bulk Collect with FORALL not working - Not enough values error
Hi,
I am trying to copy data from one table to another which are having different number of columns. I am doing the following. But it threw not enough values error.
Table A has more than 10 millions of records. So I am using bulk collect instead of using insert into select from.
TABLE A (has more columns - like 25)
c1 Number
c2 number
c3 varchar2
c4 varchar2
c25 varchar2
TABLE B (has less columns - like 7)
c1 Number
c2 number
c3 varchar2
c4 varchar2
c5 number
c7 date
c10 varchar2
declare
TYPE c IS REF CURSOR;
v_c c;
v_Sql VARCHAR2(2000);
TYPE array is table of B%ROWTYPE;
l_data array;
begin
v_Sql := 'SELECT c1, c2, c3, c4, c5, c7, c10 FROM A ORDER BY c1';
OPEN v_c FOR v_Sql;
LOOP
FETCH v_c BULK COLLECT INTO ldata LIMIT 100000;
FORALL i in 1 .. ldata.count
INSERT
INTO B
VALUES ldata(i);
END LOOP;
COMMIT;
exception
WHEN OTHERS THEN
ROLLBACK;
dbms_output.put_line('Exception Occurred' || SQLERRM);
END;
When I execute this, I am getting
PL/SQL: ORA-00947: not enough values
Any suggestions please. Thanks in advance.Table A has more than 10 millions of records. So I am using bulk collect instead of using insert into select from.That doesn't make sense to me. An INSERT ... SELECT is going to be more efficient, more maintainable, easier to write, and easier to understand.
INSERT INTO b( c1, c2, c3, c4, c5, c7, c10 )
SELECT c1, c2, c3, c4, c5, c7, c10
FROM a;is going to be faster, use fewer resources, be far less error-prone, and have a far more obvious purpose when some maintenance programmer comes along than any PL/SQL block that does the same thing.
If you insist on using PL/SQL, what version of Oracle are you using? You should be able to do something like
DECLARE
TYPE b_tbl IS TABLE OF b%rowtype;
l_array b_tbl;
CURSOR a_cursor
IS SELECT c1, c2, c3, c4, c5, c7, c10 FROM A;
BEGIN
OPEN a_cursor;
LOOP
FETCH a_cursor
BULK COLLECT INTO l_array
LIMIT 10000;
EXIT WHEN l_array.COUNT = 0;
FORALL i IN l_array.FIRST .. l_array.LAST
INSERT INTO b
VALUES l_array(i);
END LOOP;
COMMIT;
END;That at least eliminates the infinite loop and the unnecessary dynamic SQL. If you're using older versions of Oracle (it's always helpful to post that information up front), the code may need to be a bit more complex.
Justin
Edited by: Justin Cave on Jan 19, 2011 5:46 PM -
Error while doing bulk collect
Dear forum,
I am getting following error while i try to use the bulk collect
ERROR at line 1:
ORA-06500: PL/SQL: storage error
ORA-04030: out of process memory when trying to allocate 16408 bytes (koh-kghu
call ,pmuccst: adt/record)
ORA-06512: at "XLAPP14.TEST_LOAD", line 30
ORA-06512: at line 2
Pls assist
ThanksThis is a duplicate post.
Please never post more than once.
Everyone should ignore this. -
Declare
cursor c1 is select * from emp;
Type t1 is table of emp%rowtype index by binary_integer;
details t1;
rows natural:=1000;
begin
open c1;
loop
fetch c1 bulk collect into details limit rows;
exit when details.count=0;
end loop;
end;
when i compiled this program i got this below error "ORA-06550"
INTO LIST OF WRONG TYPE
I got this error in fetch statement.suggest some methods to avoid this problem.additionally,...
By Morgan
>
One should never set a limit unless it is necessary to do so. In a table with a few thousand rows using a LIMIT clause would in most cases just
increase overhead and reduce performance.
Nor would I ever advise anyone to set a limit of 1000 rows.
The number of rows in the limit clause should be tuned beginning with a minimum number of 100 and the results graphed. The number of rows
is never a direct correlation but rather rows * bytes/row so the number of rows in a table with 30 bytes per row is going to be substantially
different from that in a table with 500 bytes per row.
Please do not throw out numbers like 1000 as though there is some authoritative rationale behind them. Almost always, as in this case, there is not.
I have plenty of applications where the best number is between 5,000 and 10,000.
>
Regards,
Christian Balz -
Error during runtime when using BULK collect
Hi
CREATE OR REPLACE TYPE VAR_ROW AS OBJECT
VAR_1 VARCHAR2(20),
VAR_2 VARCHAR2(20)
CREATE OR REPLACE TYPE V_TAB AS table of VAR_ROW
CREATE OR REPLACE FUNCTION get_id RETURN var_tbl
PIPELINED AS
/* declaration */
i INTEGER;
--TYPE x_t IS TABLE OF VAR_ROW;
x_t V_TAB;
c_wip sys_refCursor;
BEGIN
c_wip := getTable('abc'); --the result return: 10 rows with 2 columns.
LOOP
FETCH c_wip BULK COLLECT
INTO x_t LIMIT 20; <-- error seems to come from this line
FOR i IN x_t.FIRST .. x_t.LAST LOOP
PIPE ROW(x_t(i).VAR_1);
--PIPE ROW(x(i).VAR_1);
END LOOP;
exit when c_wip%NOTFOUND;
end loop;
RETURN;
END;
SELECT *
FROM TABLE(get_id)
Error msg: ORA-00932:inconsistent datatypes:expected UDT got CHARWhat could be the cause of the error?In addition, if your cursor returns two separate columns, you'll have to call an appropriate object constructor to create a VAR_ROW object from the two columns. The easiest solution would be to do this in your getTable method. Where you have
SELECT column1, column2in getTable today, you'd want
SELECT var_row( column1, column2 )Otherwise, Oracle cannot construct the VAR_ROW object from the cursor, so you cannot bulk collect it into an array of VAR_ROW.
Justin
Distributed Database Consulting, Inc.
http://www.ddbcinc.com/askDDBC -
During CS5 master collection update on Windows 7, 64-bit laptop, I get the error "There was an error downloading this update. Please quit and try again later." This has been happening for the past few days. Can someone help me getting my updates?
Since CS5 is from 4+ years before the Cloud, this is not the right forum... but I don't really know a correct forum for that very old product
Have you tried to manually update the individual programs?
All updates start here and select product, read to see if you need to install updates in number order, or if the updates are cumulative for the individual product http://www.adobe.com/downloads/updates/
Maybe you are looking for
-
Order related Inter-company Billing (Third Party Order)
Hi SAP Gurus, We are using SAP R/3 4.6C version. Normally, the inter-company billing are delivery related and this is working fine. I am configuring the order related Inter-company billing, i.e. Third Party drop shipment with Inter-company. I ref
-
ITunes 11 bug - no more multiple playlist windows
Hi - Please Apple, restore the multiple window feature in iTunes so I can copy between playlists and easily add individual songs from a CD to a playlist. Why would this useful feature be removed from iTunes? I can only think that someone forgot to gi
-
Obiee 10g write back error while insertion
Hi, Im getting an error while trying to write back a column to oracle database. Error details An error occurred while writing to the server. Please check to make sure you have entered appropriate values. If the problem persists, contact your system a
-
Trouble quitting & Locked file problems in iTunes
This is weird, but it's the 2nd time it's happened in two days. I'm using the latest iTunes on OS X Tiger. I have iTunes playing music in the background while I'm working on other programs (like Word). Suddenly, I discover that I can't pull iTunes ba
-
Macbook pro 2014 retina 13 inch memory upgrade to 16gb which memory do i need to buy?
I have bought resently a macbook pro 13inch retina. i went for 8gb ram and do CAD and 3d aplications. need to upgrade to 16gb ram. i do not find anywhere not even on apple store, where you can buy RAM but not still for new model. so question, anybody