Hoy vamos a ver rápidamente un tema muy sencillo que puede traernos algun que otro dolor de cabeza. Intentar truncar una tabla de otro esquema.
Supongamos que tenemos una aplicación que utiliza dos esquemas:
ADMINISTRADOR-> Propietario de los datos y de todos los objetos del esquema
APLICACION-> Usuario de explotación de los datos que no tiene objetos propios y que accede a los datos de ADMINISTRADOR mediante grants
Este modelo de aplicación es muy común ya que nos garantiza que , el esquema APLICACION nunca va a modificar la estructura del modelo de datos, su funcionamiento se base en dar los grants
DELETE, INSERT, SELECT, UPDATE para todas las tablas del esquema ADMINISTRADOR, lo que permite a el usuario APLICACION borrar todos los datos de una tabla de ADMINISTRADOR, pero no es posible que lleve a cabo una acción de truncado, ya que , para Oracle el truncado es una acción distinta a el borrado (no lo hace sobre los datos sino sobre la propia tabla).
El problema con el que nos encontramos es que, oracle no contempla el otorgar un permiso «TRUNCATE TABLE» a un usuario sobre los objetos de otro usuario, el único permiso que contempla es el de «TRUNCATE ANY TABLE»; lo que es una brecha de seguridad ya que permitiría al usuario APLICACION el truncar cualquier tabla de cualquier otro esquema de la base datos.
¿Como se soluciona el problema?
La solución es muy sencilla, y pasa por hacer una funcion en el esquema ADMINISTRADOR que trunque la tabla que le pasamos por parámetro.
EL procedure sería tal que
create or replace procedure truncartabla(tabla_a_truncar varchar2)
is
begin
execute immediate 'truncate table ' || tabla_a_truncar ;
end;
Despues de eso , deberemos de dar permisos de ejecución sobre este procedimiento al usuario APLICACION (seguimos como usuario ADMINISTRADOR)
grant execute on truncartabla to APLICACION
Ahora ya podremos truncar tablas desde el usuario expfin, el único cambio que habrá que hacer es, en el código SQL donde pone
TRUNCATE TABLE ADMINISTRADOR.TABLA1
por
execute ADMINISTRADOR.truncartabla('TABLA1');






















