Reputation: 375
So, let's say I have a table like this one:
CREATE TABLE MEETINGS(
MEETING_DAY DATE,
MEETING_ROOM NVARCHAR2(10),
MEETING_DURATION NUMBER(2)
);
And a procedure like this one, that receives a date and a meeting room and that returns a record with the duration of the meetings that'll happen on the room on the given day:
CREATE OR REPLACE PROCEDURE meetings_for_today(
v_room IN NVARCHAR2, v_day IN DATE, result_meetings OUT SYS_REFCURSOR)
IS BEGIN
OPEN result_meetings FOR
SELECT MEETING_DAY, MEETING_DURATION
FROM MEETINGS
WHERE MEETING_DAY = v_day AND MEETING_ROOM = v_room;
END;
/
But I'd like to check if the procedure is actually working, I've search a lot on this topic, but I'm finding really difficult to find a solution.
So I've tried doing:
DECLARE
meeting_res MEETINGS%ROWTYPE;
v_refcur sys_refcursor;
BEGIN
meetings_for_today('1A', to_date('12/12/2016', 'dd/mm/yyyy'), v_refcur);
LOOP
fetch v_refcur into meeting_res;
exit when v_refcur%notfound;
dbms_output.put_line(meeting_res.MEETING_DAY || ' ' || meeting_res.MEETING_DAY);
end loop;
End;
/
Which gives me the following error:
ERROR at line 1: ORA-06504: PL/SQL: Return types of Result Set variables or query do not match ORA-06512: at line 8
What am I doing wrong?
PS: Please don't give me a code that works; explain to me what's wrong on my reasoning and how should I better use Oracle's resources :)
Upvotes: 2
Views: 1586
Reputation: 36087
PS: Please don't give me a code that works, explain me what's wrong on my reasoning and how should I better use oracle's resources :)
This variable:
meeting_res MEETINGS%ROWTYPE;
is of type: MEETINGS%ROWTYPE;
It means, that this is a row (record) that consists of all 3 columns of MEETINGS table:
CREATE TABLE MEETINGS(
MEETING_DAY DATE,
MEETING_ROOM NVARCHAR2(10),
MEETING_DURATION NUMBER(2)
);
But the cursor returns only 2 columns, look at SELECT clause here, there are only 2 columns there: MEETING_DAY + MEETING_DURATION
OPEN result_meetings FOR
SELECT MEETING_DAY, MEETING_DURATION
FROM MEETINGS .....
So, you are trying to fetch a record from this cursor which contains 2 columns, and put it into a variable that consist of 3 columns.
They certainly don't match (3 cols vs 2 cols), and you get ORA-06504 error.
You can declare your own record type that consist of 2 columns
type my_type is record(
MEETING_DAY date , MEETING_DURATION number(2)
);
and use it in your code in this way:
DECLARE
type my_type is record(
MEETING_DAY date , MEETING_DURATION number(2)
);
meeting_res my_type;
v_refcur sys_refcursor;
BEGIN
meetings_for_today('1A', to_date('12/12/2016', 'dd/mm/yyyy'), v_refcur);
LOOP
fetch v_refcur into meeting_res;
exit when v_refcur%notfound;
dbms_output.put_line(meeting_res.MEETING_DAY || ' ' || meeting_res.MEETING_DAY);
end loop;
End;
/
NOTE - the number of columns as well as types of corresponding columns must match, or at least their dattypes must be "compatibile" - they are compatibile, if Oracle is able to convert one value into another (for example NUMBER can be cast to VARCHAR2), otherwise if Oracle is not able to convert some value to another datatype, you will get ORA-06504 (for example NUMBER to DATE).
Upvotes: 2