문제

저장된 절차의 정의는 다음과 같습니다.

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;

다음은 전화입니다.

CALL usp_dropTable('SOMESCHEMA', 'SOME_TABLE');

어떤 이유로 든 즉시 실행 명령에 대한 불충분 한 권한 오류가 계속되고 있습니다. 나는 온라인을보고 불충분 한 권한 오류가 일반적으로 Oracle 사용자 계정에 패스 인 쿼리에 사용 된 명령에 대한 권한이 없다는 것을 알았습니다. 그러나 나는 낙하 특권이 있습니다. 나는 정말로 혼란스럽고 나에게 맞는 솔루션을 찾을 수없는 것 같습니다.

미리 감사드립니다.

해결책:

아래에 언급했듯이 Oracle Security Model은 절차의 어딘가에 어떤 종류의 사용을 사용 해야하는지 명시 적으로 알아야한다는 점에서 이상합니다. Oracle에 알리는 방법은 작성 또는 대체 명령문에서 Authid 키워드를 사용하는 것입니다. 절차의 제작자와 동일한 수준의 권한을 원한다면 Authid Defuler를 사용합니다. Oracle이 현재 저장된 프로 시저를 실행하는 사용자의 권한을 사용하려면 Authid current_user를 사용하려고합니다. 절차 선언은 다음과 같이 보입니다.

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;

응답 해 주셔서 감사합니다. 이것은 솔루션에 도달하는 데 확실히 성가신 문제였습니다.

도움이 되었습니까?

해결책

Oracle의 보안 모델은 즉시 실행을 사용하여 동적 SQL을 실행할 때 (PL/SQL 블록 또는 프로 시저의 컨텍스트 내에서), 사용자는 역할 멤버십을 통해 부여되는 개체 또는 명령에 대한 권한이 없습니다. 사용자는 "DBA"역할 또는 유사한 것일 가능성이 높습니다. 이 사용자에게 "드롭 테이블"권한을 명시 적으로 부여해야합니다. 다른 스키마 (예 : SYS 또는 시스템)의 테이블을 선택하려고하는 경우에도 마찬가지입니다. 해당 테이블의 명시 적 선택 권한을이 사용자에게 부여해야합니다.

다른 팁

이 예제를 사용해야합니다 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;
/

요구 사항에 대해 절차 정의 본문에서 "authid current_user"를 사용할 수 있습니다.

또는 사용자에게 부여 할 수 있습니다 DROP_ANY_TABLE 필요한 경우 권한과 절차는 변경없이 실행됩니다. 위험하지만 당신이하고있는 일에 달려 있습니다 :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top