【发布时间】:2022-01-25 18:48:43
【问题描述】:
我正在尝试组合一个过程,该过程计算表中每个 PARTITION 的行数,但出现语法错误:
错误:PROCEDURE COUNT_PARTITION 行/列:14/31 PLS-00103:在预期以下情况之一时遇到符号“(”:
我知道这不是最有效的方法,我可以使用 num_rows 列以及收集统计信息来获得相同的结果。
以下是我的测试用例。我知道问题出在“cmd”调用的构造上,但我似乎无法让它工作。任何帮助将不胜感激。
CREATE OR REPLACE PROCEDURE cmd(p_cmd varchar2)
authid current_user
is
BEGIN
dbms_output.put_line(p_cmd);
execute immediate p_cmd;
END;
/
CREATE OR REPLACE PROCEDURE
count_partition(
p_tab varchar2
) authid current_user
is
v_cnt integer;
BEGIN
for cur_rec in (select table_name, partition_name,
partition_position
FROM user_tab_partitions where table_name = p_tab order by partition_position) loop
cmd ('select count(*) /*+ parallel(a,8) */
from ' ||p_tab|| 'PARTITION ' ('||cur_rec.partition_name||')' INTO v_cnt);
DBMS_OUTPUT.PUT_LINE(cur_rec.table_name || ' ' || cur_rec.partition_name || ' ' || v_cnt || ' rows');
end loop;
END;
【问题讨论】:
-
问题不在于 cmd,您的程序有语法错误。见db<>fiddle。甚至 SQL 代码的本地语法突出显示也表明引号放错了位置。您需要更正串联
-
我知道错误在哪里。我的意思是说创建命令。为糟糕的语法道歉
-
cmd()是否总是进行计数?您不能动态传递into子句。它可以传回值或报告计数本身。 -
威廉·罗伯逊感谢您的回复。我使用 cmd 函数来执行诸如 ALTER table drop PARTITION 之类的操作……这是我第一次尝试使用它来返回计数。我不确定这是否是我收到语法错误的原因。您能否建议一个代码片段解决方法,即使这意味着不使用 cmd 函数
-
要接收来自
execute immediate的内容,您需要使用[bulk collect] into some_var。您不能将into放在普通 SQL 中,因为它没有任何外部变量。但是对于这个特定的任务,您可以在dbms_xmlgen.getxml的帮助下执行动态 SQL 语句并接收纯 SQL 的结果。见db<>fiddle