Estaba leyendo el blog de Laurent Schneider aquí. Según él, un usuario debe tener el privilegio
DROP ANY TABLE para hacer un TRUNCATE
en una tabla que pertenece a otro usuario. Esto me pareció extraño y
por eso me decidí a probarlo en Oracle 11.2.0.1. Creé un usuario (USER1) que sería el dueño de una tabla:
SQL> create user user1
2 identified by user1
3 default tablespace users
4 quota 10m on users
5 /
User created.
SQL> grant
2 create session,
3 create table,
4 select any dictionary
5 to user1
6 /
Grant succeeded.
SQL>
Luego creé un usuario (USER2) que intentaría emplear el privilegio
DROP ANY TABLE para hacer un TRUNCATE en la tabla de USER1:
SQL> create user user2
2 identified by user2
3 /
User created.
SQL> grant
2 create session,
3 drop any table to user2
4 /
Grant succeeded.
SQL>
El usuario
USER1 creó una tabla con datos:
SQL> conn user1/user1
Connected.
SQL> create table tab1 as
2 select * from dba_tables
3 /
Table created.
SQL> grant select on tab1 to user2
2 /
Grant succeeded.
SQL>
El usuario
USER2 contó las líneas en la tabla, hizo el TRUNCATE y contó las líneas otra vez para verificar que el
TRUNCATE había funcionado:
SQL> conn user2/user2
Connected.
SQL> select count(*) from user1.tab1
2 /
COUNT(*)
----------
3192
SQL> truncate table user1.tab1
2 /
Table truncated.
SQL> select count(*) from user1.tab1
2 /
COUNT(*)
----------
0
SQL>
La idea de dar el privilegio
DROP ANY TABLE al usuario USER2 me pareció peligroso y por eso lo revoqué:
SQL> conn / as sysdba
Connected.
SQL> revoke drop any table from user2
2 /
Revoke succeeded.
SQL> grant create procedure to user1
2 /
Grant succeeded.
SQL>
Entonces el usuario
USER1 creó un procedimiento para hacer un TRUNCATE en su tabla:
SQL> conn user1/user1
Connected.
SQL> create procedure truncate_tab1 as
2 begin
3 execute immediate 'truncate table tab1';
4 end;
5 /
Procedure created.
SQL>
… y le dio al usuario
USER2 el derecho de ejecutarlo:
SQL> grant execute on truncate_tab1 to user2
2 /
Grant succeeded.
SQL> insert into tab1 select * from dba_tables
2 /
3193 rows created.
SQL>
Con este procedimiento el usuario
USER2 podía todavía hacer un TRUNCATE en la tabla de USER1:
SQL> conn user2/user2
Connected.
SQL> select count(*) from user1.tab1
2 /
COUNT(*)
----------
3193
SQL> exec user1.truncate_tab1;
PL/SQL procedure successfully completed.
SQL> select count(*) from user1.tab1
2 /
COUNT(*)
----------
0
SQL>
Pero, por supuesto, no podía borrar las tablas de los otros usuarios.