Oracle ORA-00911:使用execute immediate的字符无效
下面是我用来动态创建partTiton的代码。我面临错误无效字符错误。在执行消息输出时,我没有遇到任何错误。请帮我解决这个问题Oracle ORA-00911:使用execute immediate的字符无效,oracle,Oracle,下面是我用来动态创建partTiton的代码。我面临错误无效字符错误。在执行消息输出时,我没有遇到任何错误。请帮我解决这个问题 create or replace package shs_pk_dyn_par is procedure dynamic_proc ( p_table_name in varchar2,p_month_from in number,p_month_to in number,p_status out varchar2 , p_messgae
create or replace package shs_pk_dyn_par is
procedure dynamic_proc ( p_table_name in varchar2,p_month_from in number,p_month_to in number,p_status out varchar2 , p_messgae out varchar2 );
end;
create or replace package body shs_pk_dyn_par is
procedure dynamic_proc ( p_table_name in varchar2,p_month_from in number,p_month_to in number,p_status out varchar2 , p_messgae out varchar2 ) is
v_sql varchar2(4000);
v_month_from number;
v_month_to number;
v_append number;
v_year number;
v_p_year number;
v_p_check number;
begin
p_status := 'S';
p_messgae := 'Success';
v_month_from := 0; v_month_to := 0;v_sql :=null;v_append:=null;v_year:=null;v_p_year:=null;
v_p_check := null;
v_month_from := substr(p_month_from,5,6 );
v_month_to := substr(p_month_to,5,6 );
v_year := substr(p_month_to,1,4 );
---v_sql := ' ALTER TABLE '||p_table_name||' ADD';
for i in v_month_from..v_month_to
loop
if length(i) = 1
then
v_append := 0;
else
v_append := null;
end if;
v_p_year :=null;
v_p_year := i+1;
if length(v_p_year) = 1
then
v_p_check := v_year||trim(v_append)||v_p_year;
else
v_p_check := v_year||v_p_year;
end if;
dbms_output.put_line('v_p_check'||'='||v_p_check);
if i=1
then
v_sql := ' ALTER TABLE '||p_table_name||' ADD PARTITION P_'||v_year||trim(v_append)||i||' VALUES LESS THAN ('||v_p_check||')'||';';
else
v_sql := v_sql||chr(10)||' ALTER TABLE '||p_table_name||' ADD PARTITION P_'||v_year||trim(v_append)||i||' VALUES LESS THAN ('||v_p_check||')'||';';
end if;
end loop;
dbms_output.put_line(v_sql);
begin
execute immediate ( v_sql );
exception when others
then
p_status := 'F';
p_messgae := 'Failure'||sqlerrm||dbms_utility.format_error_backtrace;
return;
dbms_output.put_line('exec'||sqlerrm||dbms_utility.format_error_backtrace);
end;
exception when others
then
p_status := 'F';
p_messgae := 'Failure'||sqlerrm||dbms_utility.format_error_backtrace;
return;
dbms_output.put_line('dynamic_proc'||sqlerrm||dbms_utility.format_error_backtrace);
end;
end;
For Execution
-----------------------------------------
declare
p_status varchar2(1);
p_message varchar2(4000);
begin
shs_pk_dyn_par.dynamic_proc('EMPLOYEES_PAR',201302,201311,p_status,p_message);
dbms_output.put_line('p_status'||'='||p_status||'='||'p_messgae'||'='||p_message);
end;
分号是语句分隔符;这是一个无效字符。您只能使用
executeimmediate
执行单个语句,不能构建一系列SQL语句并一次性执行它们。因此,您需要删除分号并将executeimmediate
移动到循环中,删除语句的串联,并从每个语句中删除最后的分号:
begin
...
loop
...
dbms_output.put_line('v_p_check'||'='||v_p_check);
v_sql := ' ALTER TABLE '||p_table_name
||' ADD PARTITION P_'||v_year||trim(v_append)||i
||' VALUES LESS THAN ('||v_p_check||')';
dbms_output.put_line(v_sql);
execute immediate ( v_sql );
end loop;
exception when others
then
p_status := 'F';
p_messgae := 'Failure'||sqlerrm||dbms_utility.format_error_backtrace;
return;
end;
(添加换行符只是为了停止代码滚动)
您还需要查看您的异常处理程序;可能只是像我所做的那样删除了附加到该子块的版本,因为它看起来有点毫无意义,但是如果您真的想,您仍然可以将每个调用包装在自己的块中
我认为您根本不需要任何异常处理程序-不知道为什么您不让调用方自己处理异常,而不是设置
out
参数。抓住别人通常是个坏主意。顺便说一句,返回后的代码将永远不会被调用。但这有点离题了…您可以只使用范围分区吗?然后将自动为您创建分区。hi Davek,同时创建表时间本身,并添加一个月的分区。以后我们需要添加一整年的分区的时候需要一个一个的添加。为了避免这种情况,我选择了这种方式。你能在这方面帮助我吗你的dbms\u输出的输出是什么?