تنفيذ فوري ضمن إجراء مخزن يحتفظ بإعطاء خطأ غير كاف من الامتيازات
-
13-09-2019 - |
سؤال
هنا هو تعريف الإجراء المخزن:
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 User لا يحتوي على امتيازات للأمر المستخدم في الاستعلام الذي يمر، وهو ما يحدث في هذه الحالة. ومع ذلك، لدي انخفاض الامتيازات. أنا مرتبك حقا ولا أستطيع أن أجد حلا يعمل بالنسبة لي.
شكرا لك مقدما.
المحلول:
نظرا لأن ستيف المذكورة أدناه، يكون نموذج أمان أوراكل غريب في أنه يحتاج إلى معرفة صراحة في مكان ما في الإجراء أي نوع من الامتيازات للاستخدام. الطريقة للسماح ل Oracle بمعرفة ذلك هو استخدام الكلمة الرئيسية المؤهلة في بيان إنشاء أو استبدال. إذا كنت ترغب في نفس المستوى من الامتيازات كخثاء الإجراء، فأنت تستخدم Author Interner. إذا كنت تريد Oracle استخدام امتيازات المستخدم قيد التشغيل حاليا الإجراء المخزن، فأنت ترغب في استخدام AuthorD 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 أو النظام) - ستحتاج إلى منح امتيازات مختارة واضحة على هذا الجدول إلى هذا المستخدم.
نصائح أخرى
يجب عليك استخدام هذا المثال مع auther 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;
/
يمكنك استخدام "Auther Current_User" في الجسم تعريف الإجراء الخاص بك لمتطلباتك.
بدلا من ذلك يمكنك منح المستخدم DROP_ANY_TABLE
امتياز إذا لزم الأمر، وسيتم تشغيل الإجراء كما هو الحال بالنسبة للحاجة إلى أي تغيير. خطير ربما ولكن يعتمد على ما تفعله :)