I'm exporting a schema from Oracle 12c to 19c and importing it in a different schema. I disabled all constraints and used delete all_tables where owner 'name of schema'. Are these the steps to disable or delete any grant in schema?
First step disabled constraints, second step used this statement:
select 'delete '||table_name||' ;'
from all_tables where owner ='name of schema';
From my point of view, you're trying to do it the wrong way. Which way is right, then? Data Pump. Here's how:
Source schema is scott; it contains tables full of data.
Connected as a privileged user (SYS), I'll create
"target" schema (mike) which is initially empty; at the end, it'll contain all tables as scott does, only empty
you don't have to do it if target user already exists in your database
a directory (Oracle object which points to a file system directory; it'll hold the dump file) and grant privileges to users so that they could use it: scott and mike
SQL> show user
USER is "SYS"
SQL> select tablespace_name from dba_tablespaces;
TABLESPACE_NAME
------------------------------
SYSTEM
SYSAUX
UNDOTBS1
TEMP
USERS
SQL> SQL> create user mike identified by lion
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;
User created.
SQL> grant create session, create table to mike;
Grant succeeded.
SQL> create directory ext_dir as 'c:\temp';
Directory created.
SQL> grant read, write on directory ext_dir to scott;
Grant succeeded.
SQL> grant read, write on directory ext_dir to mike;
Grant succeeded.
SQL>
Just to verify: mike's schema is empty:
SQL> connect mike/lion
Connected.
SQL> select * from tab;
no rows selected
SQL>
How about scott? There are number of tables, mostly full of data:
SQL> connect scott/tiger
Connected.
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BONUS TABLE
CATEGORIE TABLE
DEPT TABLE
DIM_ERS_TERM_VW TABLE
EMP TABLE
INGREDIENT TABLE
<snip>
USER_DETAILS_20211128 TABLE
21 rows selected.
SQL> select count(*) from emp;
COUNT(*)
----------
14
SQL>
OK; let's export scott's schema. No data, right? So use content parameter with metadata_only value, as well as include=table to export only tables:
SQL> $expdp scott/tiger directory=ext_dir dumpfile=scott.dmp content=metadata_only include=table
Export: Release 11.2.0.2.0 - Production on Sub Pro 4 20:39:23 2021
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
Starting "SCOTT"."SYS_EXPORT_SCHEMA_01": scott/******** directory=ext_dir dumpfile=scott.dmp content=metadata_only include=table
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Master table "SCOTT"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SCOTT.SYS_EXPORT_SCHEMA_01 is:
C:\TEMP\SCOTT.DMP
Job "SCOTT"."SYS_EXPORT_SCHEMA_01" successfully completed at 20:39:27
SQL>
Now, import into mike's schema; note the remap_schema parameter:
SQL> $impdp mike/lion directory=ext_dir dumpfile=scott.dmp remap_schema=scott:mike
Import: Release 11.2.0.2.0 - Production on Sub Pro 4 20:48:06 2021
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
Master table "MIKE"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "MIKE"."SYS_IMPORT_FULL_01": mike/******** directory=ext_dir dumpfile=scott.dmp remap_schema=scott:mike
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Job "MIKE"."SYS_IMPORT_FULL_01" successfully completed at 20:48:09
SQL>
What do we got?
SQL> connect mike/lion
Connected.
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BONUS TABLE
CATEGORIE TABLE
DEPT TABLE
DIM_ERS_TERM_VW TABLE
EMP TABLE
INGREDIENT TABLE
<snip>
USER_DETAILS_20211128 TABLE
21 rows selected.
SQL> select count(*) from emp;
COUNT(*)
----------
0
SQL>
Right; tables are here, they are empty. That's what you wanted, right?
Related
My user only has the privilege to create session, manage scheduler. But I can create tables in the schema, can I change that?
Thank you.
The if the user is able to create a table, then he has more privs than you claim. Here I create a user, grant him ONLY the privs you say, then connect as that user and try to create a table:
SQL> show user
USER is "SYSTEM"
SQL> create user beetle identified by bailey;
User created.
SQL> grant create session to beetle;
Grant succeeded.
SQL> grant manage scheduler to beetle;
Grant succeeded.
SQL> select privilege
2 from dba_sys_privs
3 where grantee='BEETLE';
PRIVILEGE
----------------------------------------
MANAGE SCHEDULER
CREATE SESSION
2 rows selected.
SQL> select granted_role
2 from dba_role_privs
3 where grantee='BEETLE';
no rows selected
SQL> select owner ||'.'||table_name,
2 privilege
3 from dba_tab_privs
4 where grantee='BEETLE';
no rows selected
SQL> -- -------- create the tables
SQL> conn beetle/bailey#pdb01
Connected.
SQL> create table my_test(dob date);
create table my_test(dob date)
*
ERROR at line 1:
ORA-01031: insufficient privileges
SQL> -- -------- load tables
SQL> -- -------- Do the query
SQL> -- -------- clean up
SQL> conn system/halftrack#pdb01
Connected.
SQL> drop user beetle cascade;
User dropped.
Please assume:
User A creates global temporary table gtt.
User A creates stored procedure sp with definer's rights AUTHID DEFINER. For simplicity, assume this sp simply inserts a row into gtt and selects a value from the row in gtt.
User A grants user B execute on sp.
What additional grants, if any, need to be given to users A and B so that B can successfully execute sp?
I've heard that when a global temporary table is used (e.g. data inserted), that the user using the global temporary table needs create table privilege to create the instance of the globaly temporary table in their session's memory (even though the global temporary table itself was already created). Is that true? I assumed granting select and insert on the global temporary table would have been sufficient.
Because sp is defined by A does this mean A needs create any table, so the row of data can be inserted and selected from user B's session memory?
Sorry, I don't currently have access to an Oracle instance where I have enough privileges to try this myself.
Please note, I am not trying to create the global temporary table in the stored procedure.
Using Oracle 19c Enterprise Edition.
Thank you in advance for helping me understand the privileges involved here.
What additional grants, if any, need to be given to users A and B so that B can successfully execute sp?
None.
SQL> show user
USER is "SCOTT"
SQL> create global temporary table gtt (name varchar2(20));
Table created.
SQL> create or replace procedure sp
2 authid definer
3 as
4 begin
5 insert into gtt (name) values (user);
6 end;
7 /
Procedure created.
SQL> exec sp;
PL/SQL procedure successfully completed.
SQL> select * from gtt;
NAME
--------------------
SCOTT
SQL> grant execute on sp to mike;
Grant succeeded.
Everything works so far for the GTT and SP owner. Let's see the grantee.
SQL> connect mike/lion
Connected.
SQL> exec scott.sp;
PL/SQL procedure successfully completed.
SQL> select * From scott.gtt;
select * From scott.gtt
*
ERROR at line 1:
ORA-00942: table or view does not exist
Right; as I said, no other privileges are needed - stored procedure works (i.e. didn't fail), but - as scott didn't grant any additional privileges, mike can't check gtt table's contents.
Back to scott:
SQL> connect scott/tiger
Connected.
SQL> select * From scott.gtt;
no rows selected
SQL>
But of course; that's a global temporary table - scott sees only its own data (which is now lost).
[EDIT: to answer questions you posted as comments]
mike had create table privilege; now it doesn't:
SQL> connect sys as sysdba
Enter password:
Connected.
SQL> revoke create table from mike;
Revoke succeeded.
This piece of code is a copy/paste from above:
SQL> connect scott/tiger
Connected.
SQL> create global temporary table gtt (name varchar2(20));
Table created.
SQL> create or replace procedure sp
2 authid definer
3 as
4 begin
5 insert into gtt (name) values (user);
6 end;
7 /
Procedure created.
SQL> exec sp;
PL/SQL procedure successfully completed.
SQL> select * from gtt;
NAME
--------------------
SCOTT
SQL> grant execute on sp to mike;
Grant succeeded.
Additionally, scott now grants select on gtt to mike:
SQL> grant select on gtt to mike;
Grant succeeded.
What does mike see now?
SQL> connect mike/lion
Connected.
SQL> exec scott.sp;
PL/SQL procedure successfully completed.
SQL> select * from scott.gtt;
NAME
--------------------
MIKE
SQL>
How to rename the table which is under other schema? For example, my user is A, I want to rename table_1 to table_1_temp which both supposed to be under the same schema, let's say schema B. Is that possible?
I tried this:
RENAME B.table_1 TO B.table_1_temp
and
RENAME B.table_1 TO table_1_temp
but got this error:
ORA-01765: specifying owner's name of the table is not allowed
ALTER statement is also doesn't work:
ALTER TABLE B.table_1 RENAME TO table_1_temp
got this error:
ORA-01031: insufficient privileges
and this
ALTER TABLE B.table_1 RENAME TO B.table_1_temp
ORA-14047 ALTER TABLE|INDEX RENAME may not be combined with other operations
"Insufficient privilege" is the keyword here. You can't modify other users' objects unless you're allowed to; of course you can't - how would it look like if anyone messes up with your schema?
Owner itself can't grant that privilege; it is a strong one and user - who is granted such a privilege - must be trustworthy as it can alter any other user's tables.
Have a look at the following example. There are two users in my database: mike (who owns a table) and scott (who should rename mike's table).
Mike and his table:
SQL> show user
USER is "MIKE"
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BEDIENSTETER TABLE
Connect as scott and try to rename mike's table (rename won't work here; it is supposed to be used in your own schema):
SQL> connect scott/tiger
Connected.
SQL> alter table mike.bediensteter rename to test;
alter table mike.bediensteter rename to test
*
ERROR at line 1:
ORA-01031: insufficient privileges
Right; insufficient privileges. What privilege is it? ALTER ANY TABLE. So let's grant it, connected as a privileged user (such as SYS in my XE database):
SQL> connect sys as sysdba
Enter password:
Connected.
SQL> grant alter any table to scott;
Grant succeeded.
OK; back to scott, repeat the action:
SQL> connect scott/tiger
Connected.
SQL> alter table mike.bediensteter rename to test;
Table altered.
Succeeded! Let's see what we've done:
SQL> connect mike/lion
Connected.
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
TEST TABLE
SQL>
Right; table is now renamed.
Rename Oracle Table or View
as you can see on this post based on Pop's answer, the RENAME statement only works for table in the same schema.
The ALTER TABLE B.table_1 RENAME TO table_1_temp looks to be the best solution, have you tried giving your user account more privileges ?
Background:
We have database FIN having schema as FIN_DEV.
We have another database APP having schema APP_DEV.
A DB link is created in APP_DEV pointing to FIN_DEV
CREATE DATABASE LINK FINDEV_FIN
CONNECT TO FIN_DEV
IDENTIFIED BY <PWD>
USING 'FIN'
We are able to access the objects in FIN_DEV from APP_DEV using
CREATE OR REPLACE SYNONYM TBL_FINA FOR TBL_FINA#FINDEV_FIN
All good until this point.
Here comes the question:
Another schema INT_DEV in APP database needs to access SYNONYM TBL_FINA from INT_DEV.
Could you please let me know the best way to accomplish this?
Here's how; I don't have your users (and don't feel like creating them), so:
my remote database = orcl (it is your fin database)
user in my remote database = my_remote_user (it is fin_dev in your database)
user in my local database = scott (app_dev in your database)
it'll create a database link and a synonym
another user in my local database = mike (int_dev in your database)
In a remote database, I'm creating a table to mimic your situation:
SQL> create table tbl_fina (id number);
Table created.
SQL> insert into tbl_fina values (1);
1 row created.
SQL> commit;
Commit complete.
SQL>
Connecting to local database, creating a database link & a synonym:
SQL> show user
USER is "SCOTT"
SQL> create database link findev_fin
2 connect to my_remote_user
3 identified by its_password
4 using 'orcl';
Database link created.
SQL> -- Testing, whether the DB link works
SQL> select * From dual#findev_fin;
D
-
X
SQL> -- Creating a snynonym
SQL> create synonym tbl_fina for tbl_fina#findev_fin;
Synonym created.
SQL> select * from tbl_fina;
ID
----------
1
SQL>
So far, so good - this is what you currently have.
Now, let's allow another user - in my local database - to access that synonym. Straightforward solution is to grant select on it, right?
SQL> grant select on tbl_fina to mike;
grant select on tbl_fina to mike
*
ERROR at line 1:
ORA-02021: DDL operations are not allowed on a remote database
SQL>
Whooops! That won't work. A workaround is to create a view (on the synonym) and grant select on that view to mike:
SQL> create view v_tbl_fina as select * from tbl_fina;
View created.
SQL> grant select on v_tbl_fina to mike;
Grant succeeded.
SQL>
That works. Finally, connect as another user and select from the view (i.e. a synonym):
SQL> connect mike/pwd
Connected.
SQL> select * from scott.v_tbl_fina;
ID
----------
1
SQL>
For easier access - to avoid naming view owner (scott) - mike can now create its own synonym:
SQL> create synonym tbl_fina for scott.v_tbl_fina;
Synonym created.
SQL> select * from tbl_fina;
ID
----------
1
SQL>
Certainly, another option is to create a database link in my mike user, but that's kind of dangerous as database link allows its owner to do virtually anything in the remote database, as it is now identified by the remote username and its password.
I have created new user and granted (database administration) privilege to him.
Then I connected to this new user.
When I create a new table in this user then try to select from this table it gives me
oracle-00942: table/view does not exist
When I try to find it through toad from schema browser I cannot find it. I searched for it and found this table in (sys) user.
When I create table with schema name I found it in schema browser but also I cannot select from it.
So what is the wrong with this?
It would help if you would show the sequence of steps you used to create the table. My guess is somehow you're creating the table under the the wrong schema (owner). Do this to find out where it is:
select owner, table_name from all_tables where table_name = 'MYTABLE'
If connected as SYS, you can use dba_tables instead of all_tables.
It would be better if you actually showed us what you did and how Oracle responded (i.e. copy/pasted the whole SQL*Plus session).
As you can create users, you probably can connect as SYS. Do so, and then run such a statement:
SQL> select owner, object_type
2 from dba_objects
3 where object_name = 'EMP';
OWNER OBJECT_TYPE
------------------------------ -------------------
SCOTT TABLE
SQL>
It will show who that table really belongs to.
I'm going to simulate what you did (actually, what I understood you did). You'll see that - if you do it right - everything is OK.
Connect as SYS and create new user:
SQL> show user
USER is "SYS"
SQL> create user utest identified by utest
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;
User created.
SQL> grant dba to utest;
Grant succeeded.
Connect as newly created user, create a table:
SQL> connect utest/utest
Connected.
SQL> create table test (id number);
Table created.
SQL> select * from test;
no rows selected
OK; the table is empty, but - no ORA-00942 error.
Back to SYS, to check who owns the TEMP table:
SQL> connect sys as sysdba
Enter password:
Connected.
SQL> select owner, object_type
2 from dba_objects
3 where object_name = 'TEST'
4 order by owner;
OWNER OBJECT_TYPE
------------------------------ -------------------
SCOTT TABLE
UTEST TABLE
SQL>
Now, it is your turn.
I searched for it and found this table in (sys) user.
It sounds like you have connected to the database using SYSDBA privilege, something like this:
connect your_user/password as sysdba
When we do this Oracle ignores the passed username and connects us as SYS. Consequently, any actions we take are executed as SYS. Which means any tables we create are created in the SYS schema, unless we prefix them with a specific schema name.