select dynamic column value from a rowtype variable in pl sql

前端 未结 2 1037
旧时难觅i
旧时难觅i 2021-01-29 01:37

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_         


        
相关标签:
2条回答
  • 2021-01-29 01:54

    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.
    
    0 讨论(0)
  • 2021-01-29 02:09

    Table:

    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.

    Query:

    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;
    /
    

    Query 2:

    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;
    /
    
    0 讨论(0)
提交回复
热议问题