una - permisos grant sql server
Ejecutar Inmediato dentro de un procedimiento almacenado sigue dando error de privilegios insuficiente (4)
Aquí está la definición del procedimiento almacenado:
CREATE OR REPLACE PROCEDURE usp_dropTable(schema VARCHAR, tblToDrop VARCHAR) IS
BEGIN
DECLARE v_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_cnt
FROM all_tables
WHERE owner = schema
AND table_name = tblToDrop;
IF v_cnt > 0 THEN
EXECUTE IMMEDIATE(''DROP TABLE someschema.some_table PURGE'');
END IF;
END;
END;
Aquí está la llamada:
CALL usp_dropTable(''SOMESCHEMA'', ''SOME_TABLE'');
Por algún motivo, sigo recibiendo un error de privilegios insuficiente para el comando EXECUTE INMEDIATE. Busqué en línea y descubrí que el error de privilegios insuficientes por lo general significa que la cuenta de usuario de Oracle no tiene privilegios para el comando utilizado en la consulta que pasa, que en este caso es DROP. Sin embargo, tengo privilegios de drop. Estoy realmente confundido y parece que no puedo encontrar una solución que funcione para mí.
Gracias a ti por adelantado.
SOLUCIÓN:
Como Steve mencionó a continuación, el modelo de seguridad de Oracle es extraño, ya que necesita saber explícitamente en algún lugar del procedimiento qué tipo de privilegios usar. La forma de avisar a Oracle es usar la palabra clave AUTHID en la instrucción CREAR O REEMPLAZAR. Si desea el mismo nivel de privilegios que el creador del procedimiento, use el DEFINICIÓN AUTHID. Si desea que Oracle use los privilegios del usuario que ejecuta actualmente el procedimiento almacenado, desea utilizar AUTHID CURRENT_USER. La declaración de procedimiento se ve de la siguiente manera:
CREATE OR REPLACE PROCEDURE usp_dropTable(schema VARCHAR, tblToDrop VARCHAR)
AUTHID CURRENT_USER IS
BEGIN
DECLARE v_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_cnt
FROM all_tables
WHERE owner = schema
AND table_name = tblToDrop;
IF v_cnt > 0 THEN
EXECUTE IMMEDIATE(''DROP TABLE someschema.some_table PURGE'');
END IF;
END;
END;
Gracias a todos por responder. Este fue sin duda un problema muy molesto para llegar a la solución.
Alternativamente, puede conceder al usuario el privilegio DROP_ANY_TABLE
si es necesario y el procedimiento se ejecutará tal cual sin necesidad de ninguna alteración. Peligroso tal vez, pero depende de lo que estés haciendo :)
Debe usar este ejemplo con AUTHID CURRENT_USER :
CREATE OR REPLACE PROCEDURE Create_sequence_for_tab (VAR_TAB_NAME IN VARCHAR2)
AUTHID CURRENT_USER
IS
SEQ_NAME VARCHAR2 (100);
FINAL_QUERY VARCHAR2 (100);
COUNT_NUMBER NUMBER := 0;
cur_id NUMBER;
BEGIN
SEQ_NAME := ''SEQ_'' || VAR_TAB_NAME;
SELECT COUNT (*)
INTO COUNT_NUMBER
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME = SEQ_NAME;
DBMS_OUTPUT.PUT_LINE (SEQ_NAME || ''>'' || COUNT_NUMBER);
IF COUNT_NUMBER = 0
THEN
--DBMS_OUTPUT.PUT_LINE(''DROP SEQUENCE '' || SEQ_NAME);
-- EXECUTE IMMEDIATE ''DROP SEQUENCE '' || SEQ_NAME;
-- ELSE
SELECT ''CREATE SEQUENCE COMPTABILITE.'' || SEQ_NAME || '' START WITH '' || ROUND (DBMS_RANDOM.VALUE (100000000000, 999999999999), 0) || '' INCREMENT BY 1''
INTO FINAL_QUERY
FROM DUAL;
DBMS_OUTPUT.PUT_LINE (FINAL_QUERY);
cur_id := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.parse (cur_id, FINAL_QUERY, DBMS_SQL.v7);
DBMS_SQL.CLOSE_CURSOR (cur_id);
-- EXECUTE IMMEDIATE FINAL_QUERY;
END IF;
COMMIT;
END;
/
El modelo de seguridad de Oracle es tal que al ejecutar SQL dinámico utilizando Execute Inmediate (dentro del contexto de un bloque o procedimiento PL / SQL), el usuario no tiene privilegios para los objetos o comandos que se otorgan a través de la membresía de roles. Su usuario probablemente tenga un rol "DBA" o algo similar. Debe otorgar explícitamente permisos de "colocar tabla" a este usuario. Lo mismo se aplicaría si estuviera intentando seleccionar de tablas en otro esquema (como sys o sistema) - tendría que conceder privilegios SELECT explícitos en esa tabla a este usuario.
puede usar "AUTHID CURRENT_USER" en el cuerpo de su definición de procedimiento para sus requisitos.