我有一个查询ALL_TAB_COLUMNS的脚本会进行一些汇总,然后通过
执行 EXECUTE IMMEDIATE vSelect into v_output;
首先,我v_output是一个整数,vSelect执行了count(*),然后返回了行数。我想将vSelect更改为实际的
SELECT * FROM ALL_TAB_COLUMNS <MY_WHERE_CLAUSE>
,然后使用DBMS_OUTPUT.PUT_LINE输出结果。我将其设置为一旦我可以将其输出就写入日志文件,但是尝试首先使其输出。甲骨文11G
答案 0 :(得分:3)
一种方法是使用记录变量all_tab_columns%rowtype
的嵌套表,然后遍历该表进行显示。
SET SERVEROUTPUT ON
DECLARE
TYPE tab_all_tab_rec IS
TABLE OF all_tab_columns%rowtype;
trec tab_all_tab_rec;
v_where_clause CLOB := 'WHERE OWNER = ''HR''';
BEGIN
EXECUTE IMMEDIATE 'SELECT *
FROM all_tab_columns ' || v_where_clause BULK COLLECT
INTO trec;
FOR i IN trec.first..trec.last LOOP
dbms_output.put_line(trec(i).owner || ',' || trec(i).table_name || ',' || trec(i).column_name
); --Other columns
END LOOP;
END;
/
O / p
HR,COUNTRIES,COUNTRY_NAME
HR,COUNTRIES,COUNTRY_ID
HR,COUNTRIES,REGION_ID
HR,DEPARTMENTS,LOCATION_ID
HR,DEPARTMENTS,MANAGER_ID
HR,DEPARTMENTS,DEPARTMENT_NAME
HR,DEPARTMENTS,DEPARTMENT_ID
HR,EMPLOYEES,DEPARTMENT_ID
HR,EMPLOYEES,MANAGER_ID
HR,EMPLOYEES,COMMISSION_PCT
HR,EMPLOYEES,SALARY
HR,EMPLOYEES,JOB_ID
HR,EMPLOYEES,HIRE_DATE
HR,EMPLOYEES,PHONE_NUMBER
HR,EMPLOYEES,EMAIL
HR,EMPLOYEES,LAST_NAME
HR,EMPLOYEES,FIRST_NAME
HR,EMPLOYEES,EMPLOYEE_ID
..
..
PL/SQL procedure successfully completed.
答案 1 :(得分:3)
这与@Kaushik的方法类似,但是使用游标循环而不是集合:
set serveroutput on
declare
l_cursor sys_refcursor;
l_row all_tab_columns%rowtype;
l_where_clause varchar2(50) := q'[where owner = 'HR']';
begin
open l_cursor for 'SELECT * FROM all_tab_columns ' || l_where_clause;
loop
fetch l_cursor into l_row;
exit when l_cursor%notfound;
dbms_output.put_line(l_row.owner ||','|| l_row.table_name ||','|| l_row.column_name);
end loop;
end;
/
它也会得到:
HR,REGIONS,REGION_NAME
HR,REGIONS,REGION_ID
HR,LOCATIONS,COUNTRY_ID
HR,LOCATIONS,STATE_PROVINCE
HR,LOCATIONS,CITY
...
尽管这样做是单独的单行读取,但是在最近的发行版中,Oracle优化了在后台使用批量操作,因此,性能应该类似于显式bulk collect
,而无需收集类型。
这假设您实际上在查询中使用select *
,所以有一个表可用于%rowtype
。如果查询更具选择性(通常是一件好事)或合并了多个表,则需要声明匹配的记录类型。