martedì 13 gennaio 2009

Script di creazione degli utenti

Problema: dato un utente residente sul db di produzione, creare un utente identico in tutto e per tutto al primo, ma sull'ambiente di test.

Soluzione: avviare EM (Enterprise Manager) con il comando emctl da lanciare da un prompt di DOS, oppure da una shell GNU/Linux (come nell'esempio seguente), previa impostazione del SID dell'istanza desiderata, perciò, da GNU/Linux:

$ export ORACLE_SID=SID
emctl start dbconsole

Enterprise Manager per Oracle 10.2.0.4 è accessibile via https all'url che viene riportato dal comando emctl stesso:
oracle@debiandb:~$ emctl start dbconsole
TZ set to Europe/Vatican
Oracle Enterprise Manager 10g Database Control Release 10.2.0.4.0
Copyright (c) 1996, 2007 Oracle Corporation. All rights reserved.
https://debiandb:5500/em/console/aboutApplication
Starting Oracle Enterprise Manager 10g Database Control ................. started.
------------------------------------------------------------------
Logs are generated in directory
/u01/app/oracle/product/10.2.0/db_1/debiandb_TEST/sysman/log

Una volta effettuato l'accesso come utente System, dalla pagina principale di EM, scegliendo il tab "Amministrazione", tra le molte voci presenti bisogna cliccare su "Utenti"; così facendo, si accede ad una pagina con la lista degli utenti del db di produzione.
Come si può notare dall'immagine sottostante, bisogna prima di tutto (punto 1) mettere il check sull'utente da copiare (nell'esempio, ho scelto l'utente ADMIN), quindi selezionare la voce "Genera DDL" dal menu a tendina (punto 2) ed infine, cliccare sul pulsante "Vai".


Ciò che si ottiene è un listato simile al seguente:
CREATE USER "ADMIN" PROFILE "DEFAULT" IDENTIFIED BY "*******"
DEFAULT TABLESPACE "TS_CNEXT" TEMPORARY TABLESPACE "TEMP"
QUOTA UNLIMITED ON "TS_CNEXT" ACCOUNT UNLOCK;
GRANT ALTER ANY INDEX TO "ADMIN";
GRANT ALTER ANY PROCEDURE TO "ADMIN";
GRANT ALTER ANY SEQUENCE TO "ADMIN";
GRANT ALTER ANY TABLE TO "ADMIN";
GRANT ALTER ANY TRIGGER TO "ADMIN";
GRANT CREATE ANY INDEX TO "ADMIN";
GRANT CREATE ANY PROCEDURE TO "ADMIN";
GRANT CREATE ANY SEQUENCE TO "ADMIN";
GRANT CREATE ANY TABLE TO "ADMIN";
GRANT CREATE ANY TRIGGER TO "ADMIN";
GRANT CREATE ANY VIEW TO "ADMIN";
GRANT CREATE PROCEDURE TO "ADMIN";
GRANT CREATE SEQUENCE TO "ADMIN";
GRANT CREATE TABLE TO "ADMIN";
GRANT CREATE TRIGGER TO "ADMIN";
GRANT CREATE VIEW TO "ADMIN";
GRANT EXECUTE ANY PROCEDURE TO "ADMIN";
GRANT INSERT ANY TABLE TO "ADMIN";
GRANT SELECT ANY SEQUENCE TO "ADMIN";
GRANT SELECT ANY TABLE TO "ADMIN";
GRANT UNDER ANY TABLE TO "ADMIN";
GRANT UNDER ANY VIEW TO "ADMIN";
GRANT "CONNECT" TO "ADMIN";

E' possibile copiare questo codice e salvarlo in un file di testo chiamato, ad esempio, "crea_admin_da_produzione.sql" (ricordate di impostare la password per l'utente sostituendola agli asterischi messi da EM).
Supponendo che i nomi delle tablespaces tra ambiente di produzione ed ambiente di test coincidano (altrimenti basta modificare lo script SQL di cui sopra), non ci sono altre modifiche da apportare al file!

Sul db di test si può quindi procedere alla creazione dell'utente, copia speculare dell'omonimo presente sul db di produzione, accedendo con un utente con il privilegio sysdba:
SQL> @crea_admin_da_produzione.sql

Et voilà, con un solo comando l'utente è stato creato, con tutti i privilegi replicati dalla produzione! In questo modo si dispone di uno schema vuoto in cui effettuare l'importazione del dump dell'utente di partenza esportato sempre dal db di produzione (cfr Oracle e i backup - Parte I).

2 commenti:

Ludovico Caldara ha detto...

con un po' di formattazione di sqlplus ricavi tutto senza em console.

in 10g con il package dbms_metadata:

select DBMS_METADATA.GET_DDL('USER', '&&user') from dual;
select DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT', '&&user') from dual;
select DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT', '&&user') from dual;
select DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', '&&user') from dual;


oppure su qualsiasi release con le viste di sistema:

select 'create user '||username||' identified by values '''||password||''' default tablespace '||
DEFAULT_TABLESPACE||' temporary tablespace '||TEMPORARY_TABLESPACE||' profile '||profile||';'
from dba_users where username ='&&user';

select 'grant '||PRIVILEGE||' to '||grantee||';' from dba_sys_privs where grantee ='&&user';

select 'grant '||granted_role||' to '||grantee||';' from dba_role_privs where grantee ='&&user' and admin_option='NO';

select 'grant '||granted_role||' to '||grantee||' with admin option;' from dba_role_privs where grantee ='&&user' and admin_option='YES';

select 'alter user '||USERNAME||' quota '||decode(MAX_BYTES,-1,'UNLIMITED',MAX_BYTES)||' on '||TABLESPACE_NAME||';' from dba_ts_quotas where username ='&&user';

ciao!

Simone Saravalli ha detto...

Ciao Ludovico, l'intento del mio post era quello di fornire un sistema "easy" per ottenere le informazioni su un certo schema di un db, ma ero comunque anche alla ricerca di un metodo da command line come quello che hai indicato tu (non sempre si può avere EM a disposizione) quindi ti ringrazio :-)

PS molto interessante il tuo blog, lo sto leggendo un pò per volta in questi giorni!