Reputation: 11
I am working with Oracle PL/SQL. There are two cursors, namely c1 and c2.
v_temp VARCHAR(50);
For s1 IN c1
LOOP
--do something
FOR s2 IN c2
LOOP
--do something
v_temp := s1.s2.xxx; --PLS-00302: component 's2' must be declared
END LOOP;
END LOOP;
s2.xxx
gives a column name, and with that column name I hope to assign the value of that column from s1
to v_temp
.
For example:
In the first iteration, s2.xxx
is 'column1'
,
I would like to assign s1.column1
to v_temp
. In the second iteration, s2.xxx
is 'column2'
, I would then like to assign s1.column2
to v_temp
.
I got the error:
Error(191,48): PLS-00302: component 's2' must be declared
while trying to compile. I know that s1.s2.xxx
is not valid, but is there another way of writing it that can make it work?
Upvotes: 1
Views: 6353
Reputation: 31656
You need to fetch from a REF CURSOR
and dynamically append the column_name to the select statement while opening the cursor. Here I am fetching all the column names from USER_TAB_COLUMNS
for table EMPLOYEES
and assigning their corresponding values to v_temp.
SET SERVEROUTPUT ON;
DECLARE
v_temp VARCHAR(50);
query1 VARCHAR2(1000);
c1 SYS_REFCURSOR;
CURSOR c2
IS
SELECT COLUMN_NAME xxx FROM USER_TAB_COLUMNS WHERE TABLE_NAME = 'EMPLOYEES';
BEGIN
FOR s2 IN c2
LOOP
--do something
query1 := 'SELECT ' ||s2.xxx||' FROM EMPLOYEES';
OPEN c1 FOR query1 ;
LOOP
FETCH c1 INTO v_temp;
DBMS_OUTPUT.PUT_LINE('COLUMN:'||s2.xxx||', VALUE:'|| v_temp);
EXIT
WHEN c1%NOTFOUND;
END LOOP;
CLOSE c1;
END LOOP;
END;
/
Since lengths of all the columns of Employees
are < 50 , it is working Fine.The conversion happens implicitly for NUMBER
and DATE
data types.
Here is a sample Output.
COLUMN:EMPLOYEE_ID, VALUE:100
COLUMN:EMPLOYEE_ID, VALUE:101
COLUMN:EMPLOYEE_ID, VALUE:102
COLUMN:FIRST_NAME, VALUE:Eleni
COLUMN:FIRST_NAME, VALUE:Eleni
COLUMN:LAST_NAME, VALUE:Whalen
COLUMN:LAST_NAME, VALUE:Fay
COLUMN:HIRE_DATE, VALUE:17-06-03
COLUMN:HIRE_DATE, VALUE:21-09-05
Upvotes: 1
Reputation: 584
I think you need smth like that:
declare
v_temp VARCHAR(50);
v_temp_1 VARCHAR(50);
cursor c2(p VARCHAR) is
SELECT *
FROM tbl
WHERE tbl.column = p;
begin
For s1 IN c1
LOOP
--do something
v_temp_1 := s1.xxx;
FOR s2 IN c2(v_temp_1)
LOOP
--do something
v_temp := s1.xxx;
END LOOP;
END LOOP;
end;
Upvotes: 1