Вывод строк столбца в переменной

Как можно сделать запрос, чтобы вывести строки по столбцу, название которого известно только после определения параметров, а именно имени таблицы и номера столбца?

DECLARE
   name_in    VARCHAR2(200) := 'DWH_gate.T$TERMINAL';
   number_in      NUMBER(30);
   sql_stmt    VARCHAR2(200);
BEGIN
   select column_name into sql_stmt
   from all_tab_columns
   where table_name like upper(SUBSTR(name_in,instr(name_in,'.',1)+1))
   and owner like upper(REGEXP_SUBSTR(name_in,'[^.]+'))
   and column_id = 3;

Соответственно, по 3-ему столбцу таблицы DWH_gate.T$TERMINAL необходимо получить данные. Но также проблема в том, что неизвестно какой тип данных будет в столбце.


Ответы (1 шт):

Автор решения: 0xdb

Можно так:

declare
    type restyp is record (numcol number, datecol date, charcol varchar2(128));
    res restyp;
    tabnam varchar2(200) := 'hr.employees';
    colnum int := 3;
    colnam varchar2 (32);
    coltyp varchar2 (8);
    rc sys_refcursor;
begin
    select column_name, data_type into colnam, coltyp
    from all_tab_columns
    where owner||'.'||table_name = upper (tabnam)
    and column_id = colnum;
    open rc for 
        ' select '||colnam||
        ' from   '||tabnam||
        ' order by 1 fetch first 3 rows only';
    dbms_output.put_line (colnam||chr(10)||'-----------------');   
    loop
        case coltyp when 'VARCHAR2' then 
            fetch rc into res.charcol;
        end case;
        exit when rc%notfound;
        case coltyp when 'VARCHAR2' then 
            dbms_output.put_line (res.charcol);
        end case;
    end loop;    
end;
/

Результат:

LAST_NAME
-----------------
Abel
Ande
Atkinson

Но лучше будет вeрнуть открытый курсор, его получатель может всегда определить тип колонки по описанию курсора. Например, IDE (SQL Developer, SQL*Plus и т.д.) сами выполнят логику loop ... case ... fetch ... из примера выше, и выведут результат из переменной подстановки rc:

var rc refcursor
declare
    tabnam varchar2(200) := 'hr.employees';
    colnum int := 3;
    colnam varchar2 (32);
begin
    select column_name into colnam
    from all_tab_columns
    where owner||'.'||table_name = upper (tabnam)
    and column_id = colnum;
    open :rc for 
        ' select '||colnam||
        ' from   '||tabnam||
        ' order by 1 fetch first 3 rows only'; 
end;
/
→ Ссылка