调用 Oracle 存储过程时参数的数量或类型错误
wrong number or types of arguments in call to Oracle stored procedure
我在下面创建了 Oracle 参数化存储过程,我试图将 Truncate
table 权限授予另一个用户,但出现 wrong number or types of arguments in call to DO_TRUNCATE
.
错误
create or replace procedure "DWH_02"."DO_TRUNCATE" (truncate_tablename NVARCHAR2)
IS
begin
EXECUTE IMMEDIATE 'TRUNCATE TABLE' || truncate_tablename;
EXECUTE IMMEDIATE 'grant execute on ' || DWH_02.DO_TRUNCATE ||' TO DWH_ST';
end;
/
您在 TRUNCATE
语句中缺少一个 space 字符,并且过程名称应该在 GRANT
语句中的字符串文字中(而不是尝试动态附加它) :
create or replace procedure "DWH_02"."DO_TRUNCATE" (truncate_tablename NVARCHAR2)
IS
begin
EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || truncate_tablename;
-- ^ Here
EXECUTE IMMEDIATE 'grant execute on DWH_02.DO_TRUNCATE TO DWH_ST';
end;
/
我也不确定在过程中包含 GRANT
的价值是什么。您只需要 运行 GRANT
一次,并且可以在程序之外使用特权用户执行此操作;显然没有必要将它包含在过程中。
同一解决方案的另一个版本,对如何截断 table 和调试以查看执行的命令有更多控制。
让我给你演示一下
SQL> create table test3.t1 ( c1 number, c2 number ) ;
Table created.
SQL> insert into test3.t1 select level, level from dual connect by level <= 10000 ;
10000 rows created.
然后我创建自己的截断过程
SQL> create or replace procedure test3.do_truncate ( ptablename in NVARCHAR2, poption in varchar2, pdebug in boolean default true )
2 is
3 vcount pls_integer;
4 vsql varchar2(400);
5 begin
6 vsql := 'truncate table ' || ptablename || ' ' || poption || ' storage ';
7 select count(*) into vcount from user_tables where table_name = upper(ptablename) ;
8 if vcount = 1
9 then
10 if pdebug
11 then
12 dbms_output.put_line(vsql);
13 end if;
14 execute immediate vsql;
15 else
16 raise_application_error(-20001,'Table '||ptablename||' does not exist in schema TEST3 ');
17 end if;
18* end;
Procedure created.
SQL> exec test3.do_truncate( 'T1' , 'REUSE' , true ) ;
truncate table T1 REUSE storage
PL/SQL procedure successfully completed.
SQL> exec test3.do_truncate( 'T2' , 'DROP' , true ) ;
BEGIN test3.do_truncate( 'T2' , 'DROP' , true ) ; END;
*
ERROR at line 1:
ORA-20001: Table T2 does not exist in schema TEST3
ORA-06512: at "TEST3.DO_TRUNCATE", line 16
ORA-06512: at line 1
如果你也想控制选项
create or replace procedure test3.do_truncate ( ptablename in NVARCHAR2, poption in varchar2, pdebug in boolean default true )
is
vcount pls_integer;
vsql varchar2(400);
begin
if upper(poption) not in ('DROP','REUSE')
then
raise_application_error(-20002,'Specify DROP or REUSE for storage option in truncate');
end if;
vsql := 'truncate table ' || ptablename || ' ' || poption || ' storage ';
select count(*) into vcount from user_tables where table_name = upper(ptablename) ;
if vcount = 1
then
if pdebug
then
dbms_output.put_line(vsql);
end if;
execute immediate vsql;
else
raise_application_error(-20001,'Table '||ptablename||' does not exist in schema TEST3 ');
end if;
end;
评论
- 最好控制程序内部的错误,以防您截断 table 它不存在。
- @MTO 已经解释的
GRANT
本身不应该在程序内部。如果你要 drop/create a table. 那将是必要的
- 您可以使用两个截断选项
reuse storage
drop storage
Specify DROP STORAGE
to deallocate all space from the deleted rows
from the table except the space allocated by the MINEXTENTS parameter
of the table or cluster. This space can subsequently be used by other
objects in the tablespace. Oracle Database also sets the NEXT storage
parameter to the size of the last extent removed from the segment in
the truncation process. This is the default.
Specify REUSE STORAGE
to retain the space from the deleted rows
allocated to the table. Storage values are not reset to the values
when the table or cluster was created. This space can subsequently be
used only by new data in the table or cluster resulting from insert or
update operations. This clause leaves storage parameters at their
current settings.
我在下面创建了 Oracle 参数化存储过程,我试图将 Truncate
table 权限授予另一个用户,但出现 wrong number or types of arguments in call to DO_TRUNCATE
.
create or replace procedure "DWH_02"."DO_TRUNCATE" (truncate_tablename NVARCHAR2)
IS
begin
EXECUTE IMMEDIATE 'TRUNCATE TABLE' || truncate_tablename;
EXECUTE IMMEDIATE 'grant execute on ' || DWH_02.DO_TRUNCATE ||' TO DWH_ST';
end;
/
您在 TRUNCATE
语句中缺少一个 space 字符,并且过程名称应该在 GRANT
语句中的字符串文字中(而不是尝试动态附加它) :
create or replace procedure "DWH_02"."DO_TRUNCATE" (truncate_tablename NVARCHAR2)
IS
begin
EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || truncate_tablename;
-- ^ Here
EXECUTE IMMEDIATE 'grant execute on DWH_02.DO_TRUNCATE TO DWH_ST';
end;
/
我也不确定在过程中包含 GRANT
的价值是什么。您只需要 运行 GRANT
一次,并且可以在程序之外使用特权用户执行此操作;显然没有必要将它包含在过程中。
同一解决方案的另一个版本,对如何截断 table 和调试以查看执行的命令有更多控制。
让我给你演示一下
SQL> create table test3.t1 ( c1 number, c2 number ) ;
Table created.
SQL> insert into test3.t1 select level, level from dual connect by level <= 10000 ;
10000 rows created.
然后我创建自己的截断过程
SQL> create or replace procedure test3.do_truncate ( ptablename in NVARCHAR2, poption in varchar2, pdebug in boolean default true )
2 is
3 vcount pls_integer;
4 vsql varchar2(400);
5 begin
6 vsql := 'truncate table ' || ptablename || ' ' || poption || ' storage ';
7 select count(*) into vcount from user_tables where table_name = upper(ptablename) ;
8 if vcount = 1
9 then
10 if pdebug
11 then
12 dbms_output.put_line(vsql);
13 end if;
14 execute immediate vsql;
15 else
16 raise_application_error(-20001,'Table '||ptablename||' does not exist in schema TEST3 ');
17 end if;
18* end;
Procedure created.
SQL> exec test3.do_truncate( 'T1' , 'REUSE' , true ) ;
truncate table T1 REUSE storage
PL/SQL procedure successfully completed.
SQL> exec test3.do_truncate( 'T2' , 'DROP' , true ) ;
BEGIN test3.do_truncate( 'T2' , 'DROP' , true ) ; END;
*
ERROR at line 1:
ORA-20001: Table T2 does not exist in schema TEST3
ORA-06512: at "TEST3.DO_TRUNCATE", line 16
ORA-06512: at line 1
如果你也想控制选项
create or replace procedure test3.do_truncate ( ptablename in NVARCHAR2, poption in varchar2, pdebug in boolean default true )
is
vcount pls_integer;
vsql varchar2(400);
begin
if upper(poption) not in ('DROP','REUSE')
then
raise_application_error(-20002,'Specify DROP or REUSE for storage option in truncate');
end if;
vsql := 'truncate table ' || ptablename || ' ' || poption || ' storage ';
select count(*) into vcount from user_tables where table_name = upper(ptablename) ;
if vcount = 1
then
if pdebug
then
dbms_output.put_line(vsql);
end if;
execute immediate vsql;
else
raise_application_error(-20001,'Table '||ptablename||' does not exist in schema TEST3 ');
end if;
end;
评论
- 最好控制程序内部的错误,以防您截断 table 它不存在。
- @MTO 已经解释的
GRANT
本身不应该在程序内部。如果你要 drop/create a table. 那将是必要的
- 您可以使用两个截断选项
reuse storage
drop storage
Specify
DROP STORAGE
to deallocate all space from the deleted rows from the table except the space allocated by the MINEXTENTS parameter of the table or cluster. This space can subsequently be used by other objects in the tablespace. Oracle Database also sets the NEXT storage parameter to the size of the last extent removed from the segment in the truncation process. This is the default.Specify
REUSE STORAGE
to retain the space from the deleted rows allocated to the table. Storage values are not reset to the values when the table or cluster was created. This space can subsequently be used only by new data in the table or cluster resulting from insert or update operations. This clause leaves storage parameters at their current settings.