Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Rick.

Asked: October 16, 2007 - 10:53 am UTC

Last updated: November 29, 2012 - 7:25 am UTC

Version: 10g

Viewed 10K+ times! This question is

You Asked

How can I migrate a user from 9i to 10g with all object rights.

and Tom said...

well, really - this sounds more like

"how can I copy a user from database 1 to database 2"

the versions are rather "not relevant", because - if you are upgrading from 9i to 10g - you should just do that - upgrade, they would be "migrated"

so you must be wanting to "move".

You can use dbms_metadata, I'm demonstrating below what happens if you have no grants (an error :( )

so if you want to do this in sql like I did, you'll have to have one of each type - else, you can do the individual sql statements one at a time

ops$tkyte%ORA9IR2> exec dbms_metadata.set_transform_param(dbms_metadata.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE);

PL/SQL procedure successfully completed.

ops$tkyte%ORA9IR2> set long 100000
ops$tkyte%ORA9IR2> select dbms_metadata.get_ddl( 'USER', 'SCOTT' ) from dual
  2  UNION ALL
  3  select dbms_metadata.get_granted_ddl( 'SYSTEM_GRANT', 'SCOTT' ) from dual
  4  UNION ALL
  5  select dbms_metadata.get_granted_ddl( 'OBJECT_GRANT', 'SCOTT' ) from dual
  6  UNION ALL
  7  select dbms_metadata.get_granted_ddl( 'ROLE_GRANT', 'SCOTT' ) from dual;

DBMS_METADATA.GET_DDL('USER','SCOTT')
-------------------------------------------------------------------------------

   CREATE USER "SCOTT" IDENTIFIED BY VALUES 'F894844C34402B67'
      TEMPORARY TABLESPACE "TEMP";



  GRANT UNLIMITED TABLESPACE TO "SCOTT";


ERROR:
ORA-31608: specified object of type OBJECT_GRANT not found
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86
ORA-06512: at "SYS.DBMS_METADATA", line 631
ORA-06512: at "SYS.DBMS_METADATA", line 1339
ORA-06512: at line 1



ops$tkyte%ORA9IR2> grant select on t to scott;

Grant succeeded.

ops$tkyte%ORA9IR2> select dbms_metadata.get_ddl( 'USER', 'SCOTT' ) from dual
  2  UNION ALL
  3  select dbms_metadata.get_granted_ddl( 'SYSTEM_GRANT', 'SCOTT' ) from dual
  4  UNION ALL
  5  select dbms_metadata.get_granted_ddl( 'OBJECT_GRANT', 'SCOTT' ) from dual
  6  UNION ALL
  7  select dbms_metadata.get_granted_ddl( 'ROLE_GRANT', 'SCOTT' ) from dual;

DBMS_METADATA.GET_DDL('USER','SCOTT')
-------------------------------------------------------------------------------

   CREATE USER "SCOTT" IDENTIFIED BY VALUES 'F894844C34402B67'
      TEMPORARY TABLESPACE "TEMP";



  GRANT UNLIMITED TABLESPACE TO "SCOTT";



  GRANT SELECT ON "OPS$TKYTE"."T" TO "SCOTT";



   GRANT "CONNECT" TO "SCOTT";

   GRANT "RESOURCE" TO "SCOTT";





You can do it this way as well:

ops$tkyte%ORA9IR2> create user a identified by a;

User created.

ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> set long 100000
ops$tkyte%ORA9IR2> set autoprint on
ops$tkyte%ORA9IR2> variable x clob
ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> select dbms_metadata.get_ddl( 'USER', 'A' ) from dual;

DBMS_METADATA.GET_DDL('USER','A')
-------------------------------------------------------------------------------

   CREATE USER "A" IDENTIFIED BY VALUES 'AFCC9478DFBF9029'
      TEMPORARY TABLESPACE "TEMP"



ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> declare
  2          no_grant exception;
  3          pragma exception_init( no_grant, -31608 );
  4  begin
  5          :x := dbms_metadata.get_granted_ddl( 'SYSTEM_GRANT', 'A' );
  6  exception
  7          when no_grant then :x := '-- no system grants';
  8  end;
  9  /

PL/SQL procedure successfully completed.


X
-------------------------------------------------------------------------------
-- no system grants

ops$tkyte%ORA9IR2> declare
  2          no_grant exception;
  3          pragma exception_init( no_grant, -31608 );
  4  begin
  5          :x := dbms_metadata.get_granted_ddl( 'OBJECT_GRANT', 'A' );
  6  exception
  7          when no_grant then :x := '-- no object grants';
  8  end;
  9  /

PL/SQL procedure successfully completed.


X
-------------------------------------------------------------------------------
-- no object grants

ops$tkyte%ORA9IR2> declare
  2          no_grant exception;
  3          pragma exception_init( no_grant, -31608 );
  4  begin
  5          :x := dbms_metadata.get_granted_ddl( 'ROLE_GRANT', 'A' );
  6  exception
  7          when no_grant then :x := '-- no role grants';
  8  end;
  9  /

PL/SQL procedure successfully completed.


X
-------------------------------------------------------------------------------
-- no role grants


Rating

  (13 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

FAN, October 17, 2007 - 12:54 pm UTC

I suggest adding:

select dbms_metadata.GET_GRANTED_DDL ('DEFAULT_ROLE', 'SCOTT') ddl_text
from dual;

Been waiting for years to catch you :)

Alexander, October 18, 2007 - 2:39 pm UTC

Why is there so much space in between grants?

Migrating a User

jean-marie faye, October 19, 2007 - 8:02 am UTC

Thanks,
But if the user has a grant (for example select) on an object of another schema, how is it possible to get it with dbms_metadata ?

How to get the tablespace quota?!

A reader, November 01, 2007 - 12:20 am UTC


Hi Tom,
If have been using a script of my own to create a user. I know that this can be used instead but it does have one missing details.
"Alter user username quota xxx/unlimited on tbs;"

How do I get the quota information?

Thanks as always..

Tom Kyte
November 02, 2007 - 11:57 am UTC

ops$tkyte%ORA10GR2> select dbms_metadata.get_ddl( 'USER', 'SCOTT' ) from dual
  2  UNION ALL
  3  select dbms_metadata.get_granted_ddl( 'SYSTEM_GRANT', 'SCOTT' ) from dual
  4  UNION ALL
  5  select dbms_metadata.get_granted_ddl( 'OBJECT_GRANT', 'SCOTT' ) from dual
  6  UNION ALL
  7  select dbms_metadata.get_granted_ddl( 'ROLE_GRANT', 'SCOTT' ) from dual
  8  union all
  9  select dbms_metadata.get_granted_ddl( 'TABLESPACE_QUOTA', 'SCOTT' ) from dual
 10  /

DBMS_METADATA.GET_DDL('USER','SCOTT')
-------------------------------------------------------------------------------

   CREATE USER "SCOTT" IDENTIFIED BY VALUES 'F894844C34402B67'
      DEFAULT TABLESPACE "USERS"
      TEMPORARY TABLESPACE "TEMP"



  GRANT SELECT ANY TRANSACTION TO "SCOTT"

  GRANT CREATE VIEW TO "SCOTT"

  GRANT UNLIMITED TABLESPACE TO "SCOTT"



  GRANT SELECT ON "SYS"."V_$PROCESS" TO "SCOTT"

  GRANT SELECT ON "SYS"."V_$SESSION" TO "SCOTT"

  GRANT SELECT ON "SYS"."DBA_DATAPUMP_JOBS" TO "SCOTT"



   GRANT "CONNECT" TO "SCOTT"

   GRANT "RESOURCE" TO "SCOTT"



  DECLARE
  TEMP_COUNT NUMBER;
  SQLSTR VARCHAR2(200);
BEGIN
  SQLSTR := 'ALTER USER "SCOTT" QUOTA UNLIMITED ON "USERS"';
  EXECUTE IMMEDIATE SQLSTR;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE = -30041 THEN
      SQLSTR := 'SELECT COUNT(*) FROM USER_TABLESPACES
              WHERE TABLESPACE_NAME = ''USERS'' AND CONTENTS = ''TEMPORARY''';
      EXECUTE IMMEDIATE SQLSTR INTO TEMP_COUNT;
      IF TEMP_COUNT = 1 THEN RETURN;
      ELSE RAISE;
      END IF;
    ELSE
      RAISE;
    END IF;
END;


Avoid Errors in Script

MZ, November 08, 2007 - 10:50 am UTC

Hi Tom,

I slightly modified your script to avoid the "not found" errors:

select (case
when ((select count(*)
from dba_users
where username = '&&Username') > 0)
then dbms_metadata.get_ddl ('USER', '&&Username')
else to_clob (' -- Note: User not found!')
end ) Extracted_DDL from dual
UNION ALL
select (case
when ((select count(*)
from dba_ts_quotas
where username = '&&Username') > 0)
then dbms_metadata.get_granted_ddl( 'TABLESPACE_QUOTA', '&&Username')
else to_clob (' -- Note: No TS Quotas found!')
end ) from dual
UNION ALL
select (case
when ((select count(*)
from dba_role_privs
where grantee = '&&Username') > 0)
then dbms_metadata.get_granted_ddl ('ROLE_GRANT', '&&Username')
else to_clob (' -- Note: No granted Roles found!')
end ) from dual
UNION ALL
select (case
when ((select count(*)
from dba_sys_privs
where grantee = '&&Username') > 0)
then dbms_metadata.get_granted_ddl ('SYSTEM_GRANT', '&&Username')
else to_clob (' -- Note: No System Privileges found!')
end ) from dual
UNION ALL
select (case
when ((select count(*)
from dba_tab_privs
where grantee = '&&Username') > 0)
then dbms_metadata.get_granted_ddl ('OBJECT_GRANT', '&&Username')
else to_clob (' -- Note: No Object Privileges found!')
end ) from dual
/

Get all grants/privileges on particular user objects to other users/roles

Megala, January 06, 2008 - 12:38 am UTC

Tom:

IS there any script or database view to get "all grants & privileges on the particular database user objects granted to other users/roles".

Can we get the same using dbms_metadata package.

Thank you
Tom Kyte
January 07, 2008 - 8:05 am UTC

example taken virtually verbaitim from the documentation for dbms_metadata...
http://docs.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_metada.htm#sthref3547

ops$tkyte%ORA10GR2> select dbms_metadata.get_dependent_ddl( 'OBJECT_GRANT', 'EMP', 'SCOTT' ) from dual;

DBMS_METADATA.GET_DEPENDENT_DDL('OBJECT_GRANT','EMP','SCOTT')
-------------------------------------------------------------------------------

  GRANT SELECT ON "SCOTT"."EMP" TO "CONNECT"

  GRANT SELECT ON "SCOTT"."EMP" TO "A"


Megala, January 07, 2008 - 1:42 pm UTC

Thanks Tom!

select dbms_metadata.GET_GRANTED_DDL('OBJECT_GRANT', '<GRANTEE>') from dual ;

is giving me all the grants on the current schema objects to grantee.

MB, April 11, 2008 - 1:06 pm UTC

Tom,
I tried this script and found that if we have only connect and system resource privilege for a user. the below script fails.

select bms_metadata.get_granted_ddl( 'SYSTEM_GRANT', USERNAME )
from dba_users

Trying to think of a query that will get me each of these values, without going to a small procedure or a anonymous block.

Any thoughts


Tom Kyte
April 11, 2008 - 2:04 pm UTC

how about getting granted the privileges to see that information?

A reader, June 20, 2008 - 4:16 am UTC

Tom,
I am just a developer but curious:

1) Are all tablespaces avaialble to all users by default and access only controlled by quota a user has?

2) Is there a Query I can do to get what are the distinct tablespaces and quotas for a user (if not extracting the DDL)
Tom Kyte
June 20, 2008 - 10:20 am UTC

1) data is released to users by "grants", if you have been granted SELECT on a table, it matters not what tablespace it is in, you can select from it.

The ability to CREATE segments in a tablespace is granted either via a grant (unlimited tablespace is a privilege, gives you the right to use anything) or by using a quota on a tablespace by tablespace basis.

So, in order to select, insert, update, delete, merge data - you need a grant on the segment (table) - the tablespace is not relevant.

In order to create new segments, you either need "unlimited tables" or a positive quota on the tablespace(s) you would like to place these segments in.


2) dba_tablespaces shows tablespaces, user_ts_quotas shows quotas

Slight modification to the sql from "MZ from Switzerland"

J.C.Narasimhan, January 11, 2010 - 1:32 pm UTC

I have slightly modified the query from "MZ from Switzerland" to get the select statements to extract the grants for all the users in the database:

---------------------------------------------
-- ###########################################
---------------------------------------------
create or replace procedure get_case_sqls_for_ddls_ver1 as

cursor get_username is
select username
from dba_users
;

begin


for l_user in get_username loop

DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE(' when ((select count(*)');
DBMS_OUTPUT.PUT_LINE(' from dba_users');
DBMS_OUTPUT.PUT_LINE(' where username = '''||l_user.username||''') > 0)');
DBMS_OUTPUT.PUT_LINE(' then dbms_metadata.get_ddl (''USER'', '''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE(' else to_clob ('' -- Note: User not found!'')');
DBMS_OUTPUT.PUT_LINE(' end ) "--Extracted_DDL" from dual');
DBMS_OUTPUT.PUT_LINE('UNION ALL');

DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE(' when ((select count(*)');
DBMS_OUTPUT.PUT_LINE(' from dba_ts_quotas');
DBMS_OUTPUT.PUT_LINE(' where username = '''||l_user.username||''') > 0)');
DBMS_OUTPUT.PUT_LINE(' then dbms_metadata.get_granted_ddl (''TABLESPACE_QUOTA'', '''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE(' else to_clob ('' -- Note: No TS Quotas found!'')');
DBMS_OUTPUT.PUT_LINE(' end ) from dual');
DBMS_OUTPUT.PUT_LINE('UNION ALL');

DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE(' when ((select count(*)');
DBMS_OUTPUT.PUT_LINE(' from dba_role_privs');
DBMS_OUTPUT.PUT_LINE(' where grantee = '''||l_user.username||''') > 0)');
DBMS_OUTPUT.PUT_LINE(' then dbms_metadata.get_granted_ddl (''ROLE_GRANT'', '''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE(' else to_clob ('' -- Note: No granted roles found!'')');
DBMS_OUTPUT.PUT_LINE(' end ) from dual');
DBMS_OUTPUT.PUT_LINE('UNION ALL');


DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE(' when ((select count(*)');
DBMS_OUTPUT.PUT_LINE(' from dba_sys_privs');
DBMS_OUTPUT.PUT_LINE(' where grantee = '''||l_user.username||''') > 0)');
DBMS_OUTPUT.PUT_LINE(' then dbms_metadata.get_granted_ddl (''SYSTEM_GRANT'', '''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE(' else to_clob ('' -- Note: No System Privileges found!'')');
DBMS_OUTPUT.PUT_LINE(' end ) from dual');
DBMS_OUTPUT.PUT_LINE('UNION ALL');

DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE(' when ((select count(*)');
DBMS_OUTPUT.PUT_LINE(' from dba_tab_privs');
DBMS_OUTPUT.PUT_LINE(' where grantee = '''||l_user.username||''') > 0)');
DBMS_OUTPUT.PUT_LINE(' then dbms_metadata.get_granted_ddl (''OBJECT_GRANT'', '''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE(' else to_clob ('' -- Note: No Object Privileges found!'')');
DBMS_OUTPUT.PUT_LINE(' end ) from dual');
DBMS_OUTPUT.PUT_LINE('/');
DBMS_OUTPUT.PUT_LINE('----------------------------------------------------------------------');

end loop;

end;
/


---------------------------------------------
--###########################################
---------------------------------------------
The above proc when called with the foll. will give the SQLs for all users:

---------------------------------------------
-- ###########################################
---------------------------------------------
set pages 50000
set serveroutput on size unlimited
spool C:\jc\workarea_av\Siebel_QA\DBMS_METADATA\sqls_gathered_frm_trial_run_1.sql
exec get_case_sqls_for_ddls_ver1
spool off
---------------------------------------------
-- ###########################################
---------------------------------------------

These SQLs generated can in turn be run as follows to get the master-list of all the grants in the database:

---------------------------------------------
-- ###########################################
---------------------------------------------
spool C:\jc\workarea_av\Siebel_QA\DBMS_METADATA\grants_by_running_trial3_ver0.0.sql
conn system/correctPW@psblprd2_taf
set long 1000000000
set pages 50000
exec DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE);
@C:\jc\workarea_av\Siebel_QA\DBMS_METADATA\sqls_gathered_frm_trial_run_1.sql
spool off
---------------------------------------------
-- ###########################################
---------------------------------------------

The above spool file grants_by_running_trial3_ver0.0.sql will be the master file of all grants for all users in the DB.

Thanks to everyone for the excellent thread/postings.

Another option

Jorge Rodriguez, February 28, 2012 - 3:30 pm UTC

Not sure if somebody already posted it, but I updated the original script based on a couple of ideas you guys provided for getting the info from all users. In this way will not fail and is not necessary to created a stored procedure.


set head off
set pages 0
set long 9999999
spool user_script.sql
SELECT DBMS_METADATA.GET_DDL('USER', USERNAME) || '/' DDL
FROM DBA_USERS
UNION ALL
SELECT DBMS_METADATA.GET_GRANTED_DDL('TABLESPACE_QUOTA', USERNAME) || '/' DDL
FROM DBA_USERS where username in (select username from dba_ts_quotas)
UNION ALL
SELECT DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT', USERNAME) || '/' DDL
FROM DBA_USERS where username in (select grantee from dba_role_privs)
UNION ALL
SELECT DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT', USERNAME) || '/' DDL
FROM DBA_USERS where username in (select grantee from dba_sys_privs)
UNION ALL
SELECT DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', USERNAME) || '/' DDL
FROM DBA_USERS where username in (select grantee from dba_tab_privs);
spool off;

Error

Girish Sharma, November 23, 2012 - 10:31 pm UTC

{CODE}
SQL> show user;
USER is "SCOTT"
SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> select dbms_metadata.get_dependent_ddl( 'OBJECT_GRANT', 'EMP', 'SCOTT' ) from dual;
ERROR:
ORA-31608: specified object of type OBJECT_GRANT not found
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86
ORA-06512: at "SYS.DBMS_METADATA", line 3915
ORA-06512: at "SYS.DBMS_METADATA", line 5770
ORA-06512: at line 1



no rows selected

SQL>
{/CODE}

How to correct above error. Please guide me.
When I Preview Review, code tag not seems working.
Thanks and Regards
Girish Sharma
Tom Kyte
November 29, 2012 - 7:25 am UTC

scott%ORA11GR2> select dbms_metadata.get_dependent_ddl( 'OBJECT_GRANT', 'EMP', 'SCOTT' ) from dual; 
ERROR:
ORA-31608: specified object of type OBJECT_GRANT not found
ORA-06512: at "SYS.DBMS_METADATA", line 5088
ORA-06512: at "SYS.DBMS_METADATA", line 7681
ORA-06512: at line 1



no rows selected

scott%ORA11GR2> grant select on emp to ops$tkyte;

Grant succeeded.

scott%ORA11GR2> select dbms_metadata.get_dependent_ddl( 'OBJECT_GRANT', 'EMP', 'SCOTT' ) from dual; 

DBMS_METADATA.GET_DEPENDENT_DDL('OBJECT_GRANT','EMP','SCOTT')
-------------------------------------------------------------------------------

  GRANT SELECT ON "SCOTT"."EMP" TO "OPS$TKYTE"




if you have no grants, it throws the exception *by design*. In your code you would catch that exception and either

a) ignore it because it is OK to have no grants

b) do something about the fact that no grants exist

Thanks

A reader, December 04, 2012 - 10:58 pm UTC

Thank you sir. This line "if you have no grants, it throws the exception *by design*." and your demo removed my doubt.

Best Regards
Girish Sharma

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here