从EXECUTE IMMEDIATE PLSQL输出结果

时间:2018-11-01 17:06:31

标签: oracle plsql oracle11g

我有一个查询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

2 个答案:

答案 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。如果查询更具选择性(通常是一件好事)或合并了多个表,则需要声明匹配的记录类型。