2009-06-15 10 views
32

देने रहता है यहां संग्रहीत प्रक्रिया की परिभाषा है:एक संग्रहीत प्रक्रिया के भीतर अपर्याप्त विशेषाधिकार त्रुटि

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; 

यहाँ कॉल है:

किसी कारण के लिए, मैं अपर्याप्त मिलती रहती है EXECUTE IMMEDIATE कमांड के लिए विशेषाधिकार त्रुटि। मैंने ऑनलाइन देखा और पाया कि अपर्याप्त विशेषाधिकार त्रुटि आमतौर पर ऑरैकल उपयोगकर्ता खाते में पास होने वाली क्वेरी में उपयोग किए गए कमांड के लिए विशेषाधिकार नहीं है, जो इस मामले में डीआरओपी है। हालांकि, मेरे पास विशेषाधिकार ड्रॉप हैं। मैं वास्तव में उलझन में हूं और मुझे ऐसा समाधान नहीं मिल रहा है जो मेरे लिए काम करता है।

अग्रिम धन्यवाद।

समाधान:

स्टीव नीचे उल्लेख किया है, ओरेकल सुरक्षा मॉडल में है कि यह स्पष्ट रूप से प्रक्रिया विशेषाधिकारों की किस तरह उपयोग करने के लिए कहीं न कहीं पता करने की जरूरत है अजीब है। ओरेकल को यह जानने का तरीका है कि CREATE या RESPLACE कथन में AUTHID कीवर्ड का उपयोग करना है। यदि आप प्रक्रिया के निर्माता के रूप में विशेषाधिकारों के समान स्तर चाहते हैं, तो आप AUTHID DEFINER का उपयोग करते हैं। यदि आप ओरेकल को वर्तमान में संग्रहीत प्रक्रिया चलाने वाले उपयोगकर्ता के विशेषाधिकारों का उपयोग करना चाहते हैं, तो आप 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; 

प्रतिक्रिया देने के लिए सभी को धन्यवाद। समाधान पाने के लिए यह निश्चित रूप से बहुत परेशान करने वाली समस्या थी।

+0

मैं इसी तरह की समस्या का सामना करना पड़ रहा था, लेकिन अजीब बात यह है कि 'AUTHID Definer' या 'AUTHID CURRENT_USER' का उपयोग किए बिना प्रक्रिया ड्रॉप तालिका के लिए क्रियान्वित किया गया है कथन लेकिन तालिका बनाने के लिए नहीं। AUTHID समाधान काम करता है :) धन्यवाद! – Aniket

+0

धन्यवाद, यह दो शब्द "AUTHID CURRENT_USER" मेरी समस्या का समाधान! धन्यवाद! – Roman

उत्तर

15

ओरेकल का सुरक्षा मॉडल ऐसा है कि निष्पादन तत्काल (पीएल/एसक्यूएल ब्लॉक या प्रक्रिया के संदर्भ में) का उपयोग कर गतिशील एसक्यूएल निष्पादित करते समय, उपयोगकर्ता को भूमिका सदस्यता के माध्यम से दी गई वस्तुओं या आदेशों के लिए विशेषाधिकार नहीं होते हैं। आपके उपयोगकर्ता की "डीबीए" भूमिका या कुछ समान है। आपको स्पष्ट रूप से इस उपयोगकर्ता को "ड्रॉप टेबल" अनुमतियां प्रदान करनी होंगी। यदि आप किसी अन्य स्कीमा (जैसे sys या system) में टेबल से चयन करने का प्रयास कर रहे थे, तो वही लागू होगा - आपको उस तालिका पर उस तालिका पर स्पष्ट SELECT विशेषाधिकार प्रदान करने होंगे।

+1

प्रतिक्रिया के लिए धन्यवाद। मैंने 'तत्काल तत्काल (' ग्रांट ड्रॉप टेबल ऑन '|| schema_name ||'। '|| tblToDrop ||' to ben '); ' लेकिन मुझे उस पंक्ति के लिए अमान्य विशेषाधिकार त्रुटि मिल रही है। मैंने तालिका छोड़ने के विशेषाधिकार को असाइन करने के लिए ऑनलाइन देखा लेकिन मुझे कुछ भी नहीं मिल रहा है। मैंने सभी की कोशिश की और "ड्रॉप टेबल" लेकिन मुझे एक ही त्रुटि मिल गई। क्या आपको पता है कि मुझे सही विशेषाधिकार का नाम कहां मिल सकता है या मैं यहां क्या गलत कर रहा हूं? एक बार फिर आपका धन्यवाद। – tundal45

+1

विशेषाधिकार प्रदान करने के लिए तत्काल तत्काल उपयोग न करें।आपको ड्रॉप टेबल विशेषाधिकार को BEN को प्रदान करने की आवश्यकता है: –

+3

स्टीव, पर अनुदान ड्रोप तालिका को मैंने अभी समझ लिया है। बाहर निकलता है मैं AUTHID का उपयोग कर प्रक्रिया के भीतर विशेषाधिकारों को परिभाषित कर सकता हूं। अगर मैं निर्माता के समान विशेषाधिकार चाहता हूं, तो मैं ऑथिड डिफिनर का उपयोग करता हूं। अगर मैं वर्तमान उपयोगकर्ता के विशेषाधिकार चाहता हूं, तो मैं AUTHID CURRENT_USER का उपयोग करता हूं। यहाँ कैसे प्रक्रिया खोल लग रहा है: बनाएं या बदलने की प्रक्रिया some_procedure AUTHID CURRENT_USER शुरू घोषित शुरू समाप्त होता है; अंत; – tundal45

0

वैकल्पिक रूप से आप उपयोगकर्ता को DROP_ANY_TABLE विशेषाधिकार प्रदान कर सकते हैं यदि आवश्यकता हो और प्रक्रिया किसी भी बदलाव की आवश्यकता के बिना चलती है। खतरनाक हो सकता है लेकिन यह निर्भर करता है कि आप क्या कर रहे हैं :)

+0

सिवाय इसके कि पहले स्थान पर विशेषाधिकार प्राप्त करने का कारण अमान्य है। साथ ही, "DROP_ANY_TABLE" को किसी भी महत्वपूर्ण आकार के निगम के लिए उत्पादन में आकस्मिक रूप से प्रदान करने की संभावना नहीं है। –

3

आप अपनी आवश्यकताओं के लिए अपनी प्रक्रिया परिभाषा के शरीर में "AUTHID CURRENT_USER" का उपयोग कर सकते हैं।

2

आप 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; 
/