Получая комментарии togetehr, вы можете использовать dbms_sql
для анализа (но не выполнения) целевого запроса и описания столбцов набора результатов для получения необходимой информации.
Из этих документов :
Каждый оператор SQL должен быть проанализирован путем вызова процедур PARSE
.Разбор оператора проверяет синтаксис оператора и связывает его с курсором в вашей программе.
Вы можете анализировать любой оператор DML или DDL.Операторы DDL выполняются при синтаксическом анализе, который выполняет подразумеваемую фиксацию.
, поскольку, поскольку оператор является просто DML, а не DDL, он будет только анализироваться и не выполняться, посколькувы не продолжите выполнение.
С фиктивной таблицей для демонстрации:
create table customer_info (association_no number(10),
col_vc varchar2(20), col_d date, col_n number(2,5), col_ts timestamp(3));
тогда базовая версия будет иметь вид:
declare
-- your target query, could be a pprocedure argument etc.
l_statement varchar2(4000) := 'SELECT A.*, A.ASSOCIATION_NO
FROM CUSTOMER_INFO A
WHERE A.ASSOCIATION_NO IS NOT NULL';
-- variabels dbms_sql use
l_c pls_integer;
l_col_cnt pls_integer;
l_desc_t dbms_sql.desc_tab4;
-- local variabels to hold columninfo as required
l_column_name all_tab_cols.column_name%type;
l_data_type varchar2(20);
begin
l_c := dbms_sql.open_cursor;
dbms_sql.parse(c=>l_c, statement=>l_statement, language_flag=>dbms_sql.native);
dbms_sql.describe_columns3(c=>l_c, col_cnt=>l_col_cnt, desc_t=>l_desc_t);
for i in 1..l_col_cnt loop
l_column_name := l_desc_t(i).col_name;
l_data_type := case l_desc_t(i).col_type
when 1 then 'VARCHAR2'
when 2 then 'NUMBER'
when 12 then 'DATE'
when 96 then 'CHAR'
when 180 then 'TIMESTAMP'
-- more types as needed
ELSE 'unknown'
end;
case
when l_desc_t(i).col_type in (1, 96) then -- or nchar etc. if needed
l_data_type := l_data_type || '(' || l_desc_t(i).col_max_len || ')';
when l_desc_t(i).col_type = 2 then
l_data_type := l_data_type || '(' || l_desc_t(i).col_precision
|| ',' || l_desc_t(i).col_scale || ')';
when l_desc_t(i).col_type = 180 then
l_data_type := l_data_type || '(' || l_desc_t(i).col_scale || ')';
else
null;
end case;
-- use for insert, or just to debug for now
dbms_output.put_line(l_column_name || ' ' || l_data_type);
end loop;
dbms_sql.close_cursor(l_c);
exception
when others then
if (dbms_sql.is_open(l_c)) then
dbms_sql.close_cursor(l_c);
end if;
raise;
end;
/
, котораядает вывод:
ASSOCIATION_NO NUMBER(10,0)
COL_VC VARCHAR2(20)
COL_D DATE
COL_N NUMBER(2,5)
COL_TS TIMESTAMP(3)
ASSOCIATION_NO NUMBER(10,0)
PL/SQL procedure successfully completed.
Если вы ожидаете другие типы данных, включите подходящую обработку для них тоже.Типы данных и эквивалентные числа перечислены в документации .
Между прочим, я связался с документами 12c и протестировал против 12cR2, поэтому я использовал новейшую структуру desc_tab4
и describe_columns3
функция.Используйте самую последнюю версию структуры / вызова, доступную для версии Oracle, против которой вы разрабатываете;если вы используете 11gR2, тогда desc_tab3
, например.Структура имеет col_type_name
, но, похоже, она не заполнена даже в 12cR2.У меня нет 18с для проверки.