Oracle 8i Stored Proc - Arrays of Different Types
Hi! New to the board. I am looking at creating an Oracle Stored Procedure and, within the procedure, want to use an array. The array needs to be able to hold different data types (i.e. VARCHAR2 and NUMBER). Is this even possible? I am under the impression that the VARRAY type can only be used for one data type. Thanks to anyone and everyone in advance! :)
James Haefner
Thursday, February 19, 2004
CREATE OR REPLACE PACKAGE DUMMY IS
type TFoo is record (
text varchar2(100),
num number
);
type TFooList is table of TFoo index by binary_integer;
procedure Init;
function Ex1(pFoo in TFoo) return number;
function Ex2 (pFoo in TFoo)return varchar2;
END;
/
CREATE OR REPLACE PACKAGE BODY DUMMY IS
procedure Init;
MyFooList TFooList;
begin
MyFooList(1).text:='Hello';
MyFooList(1).num:=100;
MyFooList(2).text:='World';
MyFooList(2).num:='200';
dbms_output.put_line(Ex1(MyFooList(1));
dbms_output.put_line(Ex2(MyFooList(1));
dbms_output.put_line(Ex1(MyFooList(2));
dbms_output.put_line(Ex2(MyFooList(2));
end;
END;
/
There you go.
HTH,
Patrik
Thursday, February 19, 2004
function Ex1(pFoo in TFoo) return number is
begin
return pFoo.num;
end;
function Ex2 (pFoo in TFoo)return varchar2 is
begin
retutn pFoo.text;
end;
There, a bit too quick posting the first reply. You get the
idea :-)
Patrik
Thursday, February 19, 2004
Thank you, Patrik. From what you provided, I was able to create the record type and implement it in the actual package body. I am running into one more problem though and don't know if there is a solution for this one.
Here is an excerpt of my code:
FOR y IN 1 .. Z LOOP --Z is a num
atotal := 0;
open c_count; --open cursor
LOOP
FETCH c_count INTO atotal;
EXIT WHEN c_count%NOTFOUND;
END LOOP;
close c_count; --close cursor
myArray(y).text:= atotal; --Doesn't work.
atotal := 0;
dateVarFrom := dateVarFrom + (7 * y);
dateVarTo := dateVarTo + (7 * y);
END LOOP;
It doesn't like the use of the variable on the left-hand side of the assignment (myArray(y).txt). The error is PLS-00308: This construct is not allowed as the origin of an assignment.
Is there someway to counteract this, or is it just not possible?
Thanks again for your help, Patrik. And thank you to anyone else who can assist me on this one.
J
James Haefner
Thursday, February 19, 2004
James,
Check to see that the cursor c_count returns a value that is compatible with MyArray.text.
Can it be that c_count is declared as cursor%rowtype ?
This test of mine works....
create package test is
type TItem is record (
test varchar2(20)
);
type TItemList is table of TItem index by binary_integer;
procedure test_proc;
end;
/
create package body test is
procedure test_proc is
ItemList TItemList;
begin
for i in 1..10 loop
ItemList(i).test:='Hello';
end loop;
for i in 1..10 loop
dbms_output.put_line(ItemList(i).text);
end loop;
end;
end;
/
So I take it, its a type missmatch problem of some kind, it is perfectly valid to use loop variables to index arrays.
In the case you rewrote some of the code for the purpose of posting it (changing variable names and such) make sure you are not using reserved words or data type names as variable names. That is illegal.
For further information, you can try searching over at
http://asktom.oracle.com
Patrik
Thursday, February 19, 2004
James,
Reading your code a bit more closely, I can see that this code will never work properly as written....
The inner loop:
LOOP
FETCH c_count INTO atotal;
EXIT WHEN c_count%NOTFOUND;
END LOOP;
Will loop over the result set each time the cursor is opened and closed; so it will always leave you with the last record in the table that c_count selects from.
You should do something along the lines of this:
y:=0;
open c_count;
LOOP
y:=y+1;
FETCH c_count INTO atotal;
if c_count is not null then
myArray(y).text:= atotal;
end if;
EXIT WHEN c_count%NOTFOUND;
END LOOP
close c_count;
and get rid of the outer loop completely. I dont know if this is what you want, but it seems more likely :-)
Since you are on Oracle 8i, you should try to use BULK FETCHES when fetching the cursors.
OPEN/FETCH/CLOSE is inefficient.
Good luck.
Patrik
Thursday, February 19, 2004
Recent Topics
Fog Creek Home
|