I need to get the specific column value from rowtype variable. My sample code is
declare
col_name varchar2(100);
col_val varchar2(100);
TYPE column_table_
You can't refer to a column/field name dynamically via another variable.
You will need to handle the whole data_table
query dynamically; this is a demo with the dbms_sql package:
declare
l_col_name varchar2(100);
l_col_val varchar2(100);
type t_col_tab is table of column_table%rowtype;
l_col_tab t_col_tab;
-- for dbms_sql
l_c pls_integer;
l_col_cnt pls_integer;
l_desc_t dbms_sql.desc_tab;
l_rc pls_integer;
l_varchar varchar2(4000);
begin
select * bulk collect into l_col_tab from column_table;
-- create cursor and prepare from original query
l_c := dbms_sql.open_cursor;
dbms_sql.parse(c=>l_c, statement=>'select * from data_table',
language_flag=>dbms_sql.native);
dbms_sql.describe_columns(c => l_c, col_cnt => l_col_cnt,
desc_t => l_desc_t);
for i in 1..l_col_cnt loop
dbms_sql.define_column(c=>l_c, position=>i,
column=>l_varchar, column_size=>4000);
end loop;
l_rc := dbms_sql.execute(c=>l_c);
while dbms_sql.fetch_rows(c=>l_c) > 0 loop
for i in 1..l_col_cnt loop
for j in 1..l_col_tab.count loop
if l_desc_t(i).col_name = l_col_tab(j).column_name then
-- same column
dbms_sql.column_value(l_c, i, l_varchar);
dbms_output.put_line('Row ' || dbms_sql.last_row_count
|| ': ' || l_desc_t(i).col_name
|| ' = ' || l_varchar);
end if;
end loop;
end loop;
end loop;
dbms_sql.close_cursor(l_c);
end;
/
The cursor query is parsed and executed, and the table descriptions allow the column names to be compared. This is just printing out the info, but you can do whatever you need with it, obviously.
With dummy tables created as:
create table data_table(id number, column_1 date, column_2 varchar2(10), column_3 varchar2(10));
insert into data_table (id, column_1, column_2, column_3) values (1, date '2017-01-01', 'dummy', 'first');
insert into data_table (id, column_1, column_2, column_3) values (2, date '2017-02-01', 'dummy', 'second');
create table column_table (column_name varchar2(30));
insert into column_table (column_name) values ('ID');
insert into column_table (column_name) values ('COLUMN_3');
... this gets output:
Row 1: ID = 1
Row 1: COLUMN_3 = first
Row 2: ID = 2
Row 2: COLUMN_3 = second
PL/SQL procedure successfully completed.
create table column_table(column_name varchar2(100), column_value varchar2(100));
You can do this without using bulk collect. Simple FOR
loop should suffice.
declare
col_name column_table.column_name%type;
col_val column_table.column_value%type;
begin
for data_table in (SELECT * FROM COLUMN_TABLE)
loop
col_name := data_table.COLUMN_NAME;
col_val := data_table.COLUMN_VALUE;
dbms_output.put_line(col_name ||' '|| col_val);
end loop;
end;
/
Using bulk collect
:
declare
col_name column_table.column_name%type;
col_val column_table.column_value%type;
type ct_tab is table of column_table%rowtype;
v_ct ct_tab;
begin
select * bulk collect into v_ct
from column_table;
for i in 1..v_ct.count loop
col_name := v_ct(i).column_name;
col_val := v_ct(i).column_value;
dbms_output.put_line(col_name ||' '|| col_val);
end loop;
end;
/