英文:
PL/SQL Dynamic Table From Cursor Select
问题
以下是翻译好的代码部分:
declare
v_table varchar2(10);
v_appname varchar2(50);
v_appcnt number;
v_cnts_appname varchar2(50);
-- 获取应用程序名称
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;
希望这对你有所帮助。如果有任何其他问题,可以随时问我。
英文:
I am trying create a PL/SQL to get sums of values from dynamic table names. I am using Oracle 11c. The table names are based off row values in another table. Rows will be added or may be deleted. Here is what I have tried that gives me the error that the table doesn't exist.
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;
答案1
得分: 0
需要使用动态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)
,但我不知道它代表什么。无论如何,现在您知道如何解决问题,可以调整您自己的代码,以便它可以编译并返回所需的结果。
英文:
You'll need dynamic SQL for that (because you have to include table name into a statement which will be executed), along with inner BEGIN-EXCEPTION-END
block which will handle errors and let loop continue to another round, without raising an error.
Sample table that contains table names:
SQL> select * from ae_apps;
TABLE_NAME
------------------------------
EMP
DEPT
DOES_NOT_EXIST
Just note that - if you wanted to fetch number of rows in those tables - you could query user_tables
. If you collect statistics regularly, num_rows
will retrieve value which was valid at the time of gathering statistics:
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
Though, if you want to do it right now, you'll have to calculate that number in your PL/SQL procedure:
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>
The last row (in output) represents table that doesn't exist, and that fact was handled in exception
section.
Code you posted fetches sum(numobjects)
, but - I don't know what it represents. Anyway, now that you know how to approach the problem, adjust your own code so that it compiles and returns desired result.
答案2
得分: 0
I need to use an execute immediate.
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;
END;
英文:
I need to use an execute immediate.
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;
END;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论