Berechtigungen für DBMS_METADATA
Seit es Datapump als Ablösung des klassischen EXP/IMP zum tranportieren von Daten gibt, gibt es auch da Package DBMS_METADATA. Das Package ist in der Lage, für vorhandene Datenbankobjekten das zughörige DDL-Statement zu dessen Erzeugung zu erstellen. Natürlich benötigt man dazu zumindest einen lesenden Zugriff auf das Data Dictionary der Oracle Datenbank. Dafür gibt es das Systemprivileg "SELECT ANY DICTIONARY". Soll ein Nutzer ohne DBA-Privilegien DDLs für beliebige Objekte erstellen können, kann man also dieses Privileg vergeben.
SQL> create user ddluser identified by "S3cre3T##";
User created.
SQL> grant create session, select any dictionary to ddluser;
Grant succeeded.
Melden wir uns also nun als dieser Benutzer an und versuchen, ein DDL-Statement zu generieren.
$ sql ddluser/S3cre3T##
SQLcl: Release 21.4 Production on Thu Oct 26 13:36:48 2023
Copyright (c) 1982, 2023, Oracle. All rights reserved.
Last Successful login time: Thu Oct 26 2023 13:36:49 +02:00
Connected to:
Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Version 19.16.0.0.0
SQL> select object_name, object_type from dba_objects where owner='DINGS';
OBJECT_NAME OBJECT_TYPE
______________ ______________
TEST TABLE
TEST2 TABLE
SQL> select dbms_metadata.get_ddl('TABLE','TEST','DINGS') from dual;
Error starting at line : 1 in command -
select dbms_metadata.get_ddl('TABLE','TEST','DINGS') from dual
Error report -
ORA-31603: object "TEST" of type TABLE not found in schema "DINGS"
ORA-06512: at "SYS.DBMS_METADATA", line 6731
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 105
ORA-06512: at "SYS.DBMS_METADATA", line 2588
ORA-06512: at "SYS.DBMS_METADATA", line 2827
ORA-06512: at "SYS.DBMS_METADATA", line 3608
ORA-06512: at "SYS.DBMS_METADATA", line 5008
ORA-06512: at "SYS.DBMS_METADATA", line 5336
ORA-06512: at "SYS.DBMS_METADATA", line 6702
ORA-06512: at "SYS.DBMS_METADATA", line 9734
ORA-06512: at line 1
Das ist überraschend. Eine Recherche bei MyOracleSupport bringt ein Dokument zu Tage, das zumindest einen Hinweis auf eine mögliche Ursache gibt: Oracle Error ORA-31603 Encountered (Doc ID 2887089.1). Dort ist von der Rolle SELECT_CATALOG_ROLE die Rede. Man hätte natürlich auch die Dokumentation lesen können. Also probieren wir das aus.
SQL> grant select_catalog_role to ddluser;
Grant succeeded.
Mit diesem Rolle, die natürlich auch aktiviert sein muss, können wir nun auch das DDL-Statement erfolgreich erzeugen:
SQL> select * from user_role_privs;
USERNAME GRANTED_ROLE ADMIN_OPTION DELEGATE_OPTION DEFAULT_ROLE OS_GRANTED COMMON INHERITED
___________ ______________________ _______________ __________________ _______________ _____________ _________ ____________
DDLUSER SELECT_CATALOG_ROLE NO NO YES NO NO NO
SQL>
SQL> select dbms_metadata.get_ddl('TABLE','TEST','DINGS') from dual;
DBMS_METADATA.GET_DDL('TABLE','TEST','DINGS')
___________________________________________________________________________________
CREATE TABLE "DINGS"."TEST"
( "USERNAME" VARCHAR2(128) NOT NULL ENABLE,
[...]
Die Rolle SELECT_CATALOG_ROLE vereint im Grunde SELECT-Berechtigungen auf alle Views im Data Dictionary. Offenbar macht das für das Package DBMS_METADATA einen Unterschied. Ein kleiner Fakt, der vielleicht einigen Ärger ersparen kann.
Kommentare
Keine Kommentare