Эта процедура получает текст SQL-запроса (из безопасного источника - обратите внимание, что в противном случае вам следует реализовать некоторые базовые проверки на наличие вредоносного кода) вместе с количеством столбцов, которые вы хотите получить.
Процедура анализирует запрос, динамически определяет столбцы в необходимом количестве и выбирает строки для создания DBMS_OUTPUT - вы должны получить идею для своего варианта использования.
Вы можете опустить col_cnt
параметр и получить значение от курсора, используя DBMS_SQL.DESCRIBE_COLUMNS
, но это потребует дополнительного открытия / закрытия курсора.
CREATE OR REPLACE PROCEDURE ftch (
sql_txt IN VARCHAR2,
col_cnt IN NUMBER) IS
type array_vc_t is varray(100) of varchar2(30);
id NUMBER;
cols array_vc_t := array_vc_t();
source_cursor INTEGER;
ignore INTEGER;
BEGIN
source_cursor := dbms_sql.open_cursor;
DBMS_SQL.PARSE(source_cursor,sql_txt, DBMS_SQL.NATIVE);
DBMS_SQL.DEFINE_COLUMN(source_cursor, 1, id);
for i in 1..col_cnt loop
cols.extend();
DBMS_SQL.DEFINE_COLUMN(source_cursor, i+1, cols(i), 30);
end loop;
ignore := DBMS_SQL.EXECUTE(source_cursor);
LOOP
IF DBMS_SQL.FETCH_ROWS(source_cursor)>0 THEN
DBMS_SQL.COLUMN_VALUE(source_cursor, 1, id);
for i in 1..col_cnt loop
DBMS_SQL.COLUMN_VALUE(source_cursor, i+1, cols(i));
end loop;
dbms_output.put_line('id= '|| id );
for i in 1..col_cnt loop
dbms_output.put_line(' i='|| i || ' col = '|| cols(i) );
end loop;
ELSE
-- No more rows - exit
EXIT;
END IF;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(source_cursor);
EXCEPTION
WHEN OTHERS THEN
IF DBMS_SQL.IS_OPEN(source_cursor) THEN
DBMS_SQL.CLOSE_CURSOR(source_cursor);
END IF;
RAISE;
END;
/
пример
exec ftch('select id, col1, col2 from tab',2);
вывод
id= 1
i=1 col = xx1
i=2 col = xx2
id= 2
i=1 col = yy1
i=2 col = yy2
id= 3
i=1 col = zz1
i=2 col = zz2