2010-03-04 15 views
8

soy sobre todo un novato oráculo, así que perdónenme si esto es una pregunta estúpida ...Ejecución de una Proc almacenado de Oracle como otro usuario

tengo un esquema denominado 'código' con un procedimiento almacenado que se ejecuta arbitraria SQL (por ahora, ignore los posibles problemas de seguridad asociados con eso). El SQL que se transfiere seleccionará los datos; pero todos los datos residen en el esquema A, B o C, pero el SQL solo seleccionará de UN esquema a la vez.

Por ejemplo: el usuario del tipo A crea una cadena 'SELECCIONAR * FROM A.USERTABLE' - mientras que el usuario del tipo B crea una cadena 'SELECCIONAR * FROM B.USERTABLE'.

Lo que trato de hacer es permitir que el usuario no especifique explícitamente su esquema. En la aplicación front-end .net; Ya sé si son de tipo A, B o C. Quiero que los tres simplemente ingresen 'SELECCIONAR * DE USUARIO'.

El problema que tengo es que no sé cómo hacer eso. Mi aplicación solo puede ejecutar proc en el esquema 'CODE', por lo que no puedo simplemente duplicar el código y dejar que el usuario A llame 'A.ExecuteSQL'.

He intentado algunas cosas; pero nada ha funcionado hasta ahora. Quiero que el proc ExecuteSQL permanezca en el esquema de CÓDIGO; pero cuando se transfiere 'USERTABLE', necesito que sepa que a veces eso significa A.USERNAME y a veces B.USERNAME.

¿Alguna sugerencia?

Respuesta

10

Uso:

ALTER SESSION SET CURRENT_SCHEMA = schema 

Esa es la equivalent to SQL Server's EXECUTE AS syntax.

+0

¿Cómo funciona esto? La primera aplicación ejecuta esta sentencia 'ALTER' o la ejecuta en el procedimiento' CODE'? – Guru

+1

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:588045400346317188 tiene algo más de información. Parece que puede hacerlo con sql dinámico (ejecutar de inmediato) dentro de su proceso almacenado. –

+0

@Guru: ver el enlace AskTom de Rob P –

7

Otra opción sería utilizar el pragma AUTHID CURRENT_USER.

Si agrega estas dos palabras clave inmediatamente después de su paquete, procedimiento, función o nombre de tipo, se ejecutará con los privilegios del usuario ejecutante, en lugar del esquema de CÓDIGO. Esto anula el comportamiento por defecto que es AUTHID DEFINER (los privilegios del esquema/usuario que compilan el código)

es decir

CREATE FUNCTION examplefunc 
    (pSqlStatement IN VARCHAR2) 
RETURN INTEGER 
    AUTHID CURRENT_USER 
AS 
    lResult INTEGER; 
BEGIN 
    EXECUTE IMMEDIATE pSqlStatement INTO lResult; 
    RETURN lResult; 
END examplefunc; 

Tenga en cuenta que para las funciones y los procedimientos de información privilegiada de un paquete, el pragma sólo se puede aplicar a nivel de paquete No puede establecer los derechos por función.

Esto debería hacer que cualquier SQL dentro de la función, paquete, etc., se ejecute con los privilegios de los usuarios.

Lo he usado para administrar una rutina similar 'ejecutar cualquier bit de SQL dinámicamente' - al menos habrá impedido que un usuario 'normal' pueda usar su procedimiento almacenado para soltar una tabla o instalar código adicional en el esquema de CÓDIGO.

(También puede valer la pena, si no lo ha hecho ya, agregar alguna validación para descartar ciertas palabras clave, es decir, debe comenzar con SELECT, no debe contener bloques pl/sql incrustados, lo que sea que pueda conseguir sin romper código existente).

Cuestiones relacionadas