Home > Net >  wrong number or types of arguments in call to Oracle stored procedure
wrong number or types of arguments in call to Oracle stored procedure

Time:10-12

I have created below Oracle parameterized stored procedure where i am trying to grant Truncate table priviledge to another user but getting error as 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;
/

CodePudding user response:

You are missing a space character in the TRUNCATE statement and the procedure name should be in the string literal in the GRANT statement (rather than trying to dynamically append it):

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;
/

I am also not sure what the value of including the GRANT in the procedure is. You only need to run the GRANT once and could do that with a privileged user outside of the procedure; there is no apparent need to include it inside the procedure.

CodePudding user response:

Another version of the same solution with a bit more of control on how to truncate the table and a debug to see the command executed.

Let me show you the demo

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.

Then I create my own truncate procedure

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

If you want to control the option as well

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;

Comments

  • It is better to control the error inside the procedure in case you are truncating table that it does not exist.
  • The GRANT itself as @MTO has already explain should not be inside the procedure. That would be necessary if you were to drop/create a table.
  • You can use two options for truncate
    • 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.

  • Related