oracle PL/SQL动态表从游标选择

nwnhqdif  于 2023-03-07  发布在  Oracle
关注(0)|答案(2)|浏览(196)

我正在尝试创建PL/SQL以从动态表名获取值的总和。我使用的是Oracle 11 c。表名基于另一个表中的行值。行将被添加或删除。以下是我所尝试的操作,但出现了表不存在的错误。

set serveroutput on;


declare 

v_table         varchar2(10);
v_appname       varchar2(50);
v_appcnt        number;
v_cnts_appname  varchar2(50);

-- get app names
cursor appid_cur is
select 'ae_dt'||APPID, APPNAME from AE_APPS;

begin
open appid_cur;
loop
    fetch appid_cur into v_table, v_appname;
      FOR Cur_Rec IN (SELECT sum(NUMOBJECTS) cnt FROM v_table) LOOP
          dbms_output.put_line(v_appname||', '||Cur_Rec.cnt);
      END LOOP;
    close appid_cur;
 END LOOP;
 
 END;
zf9nrax1

zf9nrax11#

为此,您需要动态SQL(因为您必须将表名包含在将要执行的语句中),沿着内部BEGIN-EXCEPTION-END块,该块将处理错误并让循环继续到另一轮,而不会引发错误。
包含表名的示例表:

SQL> select * from ae_apps;

TABLE_NAME
------------------------------
EMP
DEPT
DOES_NOT_EXIST

请注意,如果您想获取这些表中的行数,您可以查询user_tables。如果您定期收集统计信息,num_rows将检索在收集统计信息时有效的值:

SQL> select table_name, num_rows from user_tables
  2  where table_name in ('EMP', 'DEPT', 'DOES_NOT_EXIST');

TABLE_NAME                         NUM_ROWS
------------------------------ ------------
DEPT                                      4
EMP                                      14

但是,如果您想 * 现在 * 就执行,则必须在PL/SQL过程中计算该数字:

SQL> set serveroutput on
SQL> declare
  2    l_str varchar2(200);
  3    l_cnt number;
  4  begin
  5    for cur_r in (select table_name from ae_apps) loop
  6      begin
  7        l_str := 'select count(*) from ' || cur_r.table_name;
  8        execute immediate l_str into l_cnt;
  9        dbms_output.put_Line(cur_r.table_name ||': '|| l_cnt);
 10      exception
 11        when others then
 12          dbms_output.put_line(cur_r.table_name ||': '|| sqlerrm);
 13      end;
 14    end loop;
 15  end;
 16  /
EMP: 14
DEPT: 4
DOES_NOT_EXIST: ORA-00942: table or view does not exist

PL/SQL procedure successfully completed.

SQL>

最后一行(在输出中)表示不存在的表,这个事实在exception节中处理。
你发布的代码获取sum(numobjects),但是--我不知道它代表什么。不管怎样,现在你知道了 * 如何 * 处理这个问题,调整你自己的代码,使它编译并返回所需的结果。

h7appiyu

h7appiyu2#

我需要使用立即执行。

DECLARE
   CURSOR cv_table IS select 'ae_dt'||APPID, APPNAME from AE_APPS;
   v_table         varchar2(10);
   v_appname       varchar2(50);
   c number;
BEGIN
   OPEN cv_table;
   LOOP
      FETCH cv_table INTO v_table, v_appname;
      EXIT WHEN cv_table%NOTFOUND;
      execute immediate 'SELECT sum(NUMOBJECTS) FROM '|| v_table into c;
     dbms_output.put_line(v_appname||' Number of document pages: '||to_char (c) );
  END LOOP;

结束;

相关问题