Recompiling a synonym in another schema of Oracle DB - oracle

I want to recompile a broken synonym in another schema but get an error about privileges.
As per Oracle states:
To modify a private synonym in another user's schema, you must have the CREATE ANY SYNONYM and DROP ANY SYNONYM system privileges.
Okay, see my snippet:
SQL*Plus: Release 11.2.0.1.0 Production on Thu Sep 24 18:47:29 2020
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Release 11.2.0.4.0 - 64bit Production
SQL> select user, sys_context( 'userenv', 'current_schema' ) cur_schema from dual;
USER
------------------------------
CUR_SCHEMA
--------------------------------------------------------------------------------
STAT_ADM
STAT_ADM
SQL> SELECT s.privilege
2 FROM dba_sys_privs s
3 WHERE s.grantee = USER
4 AND s.privilege LIKE '%ANY%SYNONYM%';
PRIVILEGE
----------------------------------------
DROP ANY SYNONYM
CREATE ANY SYNONYM
SQL> alter synonym ADB011_T_PRO.SA_BRAND compile;
alter synonym ADB011_T_PRO.SA_BRAND compile
*
ERROR at line 1:
ORA-01031: insufficient privileges
SQL> select dbms_metadata.get_ddl(object_type => 'SYNONYM'
2 ,NAME => 'SA_BRAND'
3 ,SCHEMA => 'ADB011_T_PRO') ddl_code from dual;
DDL_CODE
--------------------------------------------------------------------------------
CREATE OR REPLACE SYNONYM "ADB011_T_PRO"."SA_BRAND" FOR "STAT_INT"."SA_BRAND"
SQL>
Do I really lack of some permission? Or how should I properly recompile synonym? I have also CREATE ANY SYNONYM permission so I workaround it by issuing DDL statement of this synonym to make it valid again but I want to use a compile option.

This does seem to be documented as Oracle Bug 4189542 (Doc ID 4189542.8). From your code, it looks like you are using a version 11.2.0.4 database. If you update your version of Oracle, or apply a recent patch set to your 11.2.0.4 database, then it should resolve the issue.

Related

CREATE ANY TABLE not sufficient for creating any table?

I use the SYSTEM user to grant CREATE ANY TABLE to user TEST, but when I try to execute
create table other.dummy ...
I still get ORA-01031: insufficient privileges
Oracle : Grant Create table in another schema? claims this should work.
I tried to also grant CREATE ANY INDEX since the table has PK and therefore includes an index, but that didn't change anything.
GRANT ALL PRIVILEGES did the trick but I'd prefer something more limited.
The actual CREATE TABLE statement is:
CREATE TABLE OTHER.DUMMY_ENTITY (
ID NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY,
NAME VARCHAR2(30)
)
What privileges do I need to grant beyond CREATE ANY TABLE?
When you grant the privilege CREATE ANY TABLE to a specific user, the user will be able to create any table in the database, as long as the creation of such table is compatible with the statement you are running. In your case, you are not just creating a table.
Let's simulate your scenario, by creating a user with such privilege and then trying to create the table in another schema.
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Nov 5 10:54:17 2021
Version 19.6.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.6.0.0.0
SQL> show user
USER is "SYS"
SQL>
SQL> create user test_grant identified by "Oracle_123" ;
User created.
SQL> grant create session, create any table to test_grant ;
Grant succeeded.
SQL> exit
Now, I am connecting with test_grant to create a table as yours in the schema test
sqlplus test_grant/"Oracle_123"
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Nov 5 10:55:28 2021
Version 19.6.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.6.0.0.0
SQL> create table test.t1_privs ( c1 number generated by default on null as identity primary key , c2 varchar2(1) ) ;
create table test.t1_privs ( c1 number generated by default on null as identity primary key , c2 varchar2(1) )
*
ERROR at line 1:
ORA-01031: insufficient privileges
SQL> create table test.t2_privs ( c1 number, c2 varchar2(1) ) ;
Table created.
As you can see, I can create a table in other schema, but not the one you want to create. Obviously elements inside your create table statement require other privileges, so let's analyse them
Identity column contains a sequence
Primary Key contains an index.
Let's give the user those any privileges
SQL> grant create any index, create any sequence to test_grant ;
Grant succeeded.
Try again
sqlplus test_grant/"Oracle_123"
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Nov 5 11:06:47 2021
Version 19.6.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Last Successful login time: Fri Nov 05 2021 11:03:31 +01:00
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.6.0.0.0
SQL> create table test.t1_privs ( c1 number generated by default on null as identity primary key , c2 varchar2(1) ) ;
create table test.t1_privs ( c1 number generated by default on null as identity primary key, c2 varchar2(1) )
*
ERROR at line 1:
ORA-01031: insufficient privileges
So, what is happening ?
When you create a table in another schema with a column as identity, you need not only the create any table and the create any sequence privileges, you also need the select any sequence privilege
SQL> grant select any sequence to test_grant ;
Grant succeeded.
sqlplus test_grant/"Oracle_123"
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Nov 5 11:31:44 2021
Version 19.6.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Last Successful login time: Fri Nov 05 2021 11:29:36 +01:00
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.6.0.0.0
SQL> create table test.t1_privs ( c1 number generated by default on null as identity primary key, c2 varchar2(1) ) ;
Table created.

Set PLSQL_CCFLAGS for the schema

There are several schemas in my database. Some of them are for debugging (we call them DEV schemas) and the others are for production. To differ the DEV schemas from others we use one package which has function named is_debug. In default it return false. To make the schemas as DEV we replace this package with the function that returns true and compile it.
But, recently I learned about Conditional-compilation and PLSQL_CCFLAGS. And I think it could be better to use flags to differ the DEV schemas from others. But it can be set to the DATABASE and SESSION only. I want to set it to the SCHEMA, so that the every package in this schema can use it. Is it possible?
As the documentation states
PLSQL_CCFLAGS provides a mechanism that allows PL/SQL programmers to
control conditional compilation of each PL/SQL library unit
independently.
And can only be changed at session or system level
Modifiable ALTER SESSION, ALTER SYSTEM
However, you might overcome this limitation by using a logon trigger. Let's imagine you want to change this debug to true when anyone is connecting with the SCHEMA_DEV , and leave it as false when they connect with any other one
create or replace trigger sys.logon_flags_plsql
after logon on database
declare
v_true varchar2(200) := 'ALTER SESSION SET PLSQL_CCFLAGS = ''debug:TRUE'' ';
v_false varchar2(200) := 'ALTER SESSION SET PLSQL_CCFLAGS = ''debug:FALSE'' ';
v_user varchar2(128);
v_os_user varchar2(128);
begin
SELECT UPPER(SYS_CONTEXT ('USERENV', 'SESSION_USER')),
UPPER(SYS_CONTEXT('USERENV', 'OS_USER')),
INTO
v_user,
v_os_user
FROM DUAL;
--
if v_user in ( 'SCHEMA_PRE', 'SCHEMA_PRO' )
then
execute immediate v_false;
elsif v_user = 'SCHEMA_DEV'
then
execute immediate v_true;
else
null; -- or whatever you consider to
end if;
end;
/
One advantage of using logon triggers is that you can apply a lot of settings to connections coming from users, operating system users, and any other property you can think of available in the default context sys_context
However, this solution will only work as long as the users are not setting the flag by themselves. Keep in mind that the privilege alter session to modify any parameter is inherited by the privilege create session.
Demo of this ( as sys we create an user with only create session privilege )
SQL> create user test3 identified by Oracle_1234 ;
User created.
SQL> grant create session to test3 ;
Grant succeeded.
SQL> exit
Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.6.0.0.0
Connected as this user with only create session privilege
$ sqlplus test3/Oracle_1234
SQL*Plus: Release 19.0.0.0.0 - Production on Mon Oct 4 14:39:47 2021
Version 19.6.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.6.0.0.0
SQL> alter session SET PLSQL_CCFLAGS = 'debug:FALSE' ;
Session altered.
SQL>
So, as long as your users are not kind of "cheating" this could solve the issue at schema level, applying the alter session you want depending on who is connecting. Of course, if you are using personal users with privileges over the schema, you have to use another logic if you want to make it work. I think you get the idea.

How to export schema and its data with TOAD

On TOAD there are many options to export data.
What I want to do is to export a schema/user and its related object (tablespace, sequences, etc) in order to import it on another oracle installation on another machine.
Is there a specific option suitable for my goal?
I wouldn't do it with TOAD, but from command prompt, using Data Pump Export and Import on command prompt. Here's an example.
First, as SYS, create a directory (Oracle object) which points to directory (folder) on my hard disk drive. Grant required privileges on it to user which will be using it.
SQL> show user
USER is "SYS"
SQL> create directory my_dir as 'c:\temp';
Directory created.
SQL> grant read, write on directory my_dir to mdp;
Grant succeeded.
As MDP (it is user I created while answering your other question, here: What are roles and privileges to give a user in order to perform CRUD(on Oracle 12)), create some objects:
SQL> connect mdp/pdm#xe
Connected.
SQL> create table test (id number);
Table created.
SQL> create view v_test as select * From test;
View created.
SQL> insert into test
2 select level from dual
3 connect by level <= 5;
5 rows created.
SQL> commit;
Commit complete.
OK, operating system level, command prompt: export the user:
C:\>expdp mdp/pdm#xe directory=my_dir file=mdp.dmp log=mdp_exp.log
Export: Release 11.2.0.2.0 - Production on Ned Vel 3 18:00:54 2019
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
Legacy Mode Active due to the following parameters:
Legacy Mode Parameter: "file=mdp.dmp" Location: Command Line, Replaced with: "dumpfile=mdp.dmp"
Legacy Mode Parameter: "log=mdp_exp.log" Location: Command Line, Replaced with: "logfile=mdp_exp.log"
Legacy Mode has set reuse_dumpfiles=true parameter.
Starting "MDP"."SYS_EXPORT_SCHEMA_01": mdp/********#xe directory=my_dir dumpfile=mdp.dmp logfile=mdp_exp.log reuse_dumpfiles=true
Estimate in progress using BLOCKS method...
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
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/VIEW/VIEW
. . exported "MDP"."TEST" 5.031 KB 5 rows
Master table "MDP"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for MDP.SYS_EXPORT_SCHEMA_01 is:
C:\TEMP\MDP.DMP
Job "MDP"."SYS_EXPORT_SCHEMA_01" successfully completed at 18:01:24
C:\>
Nice; exported successfully.
Now, using SYS Oracle user, I'll drop MDP user; CASCADE is used because user has some objects which have to be dropped too. Why am I dropping it? To simulate your case, i.e. moving the DMP file to another computer/database which doesn't contain that user.
C:\>sqlplus sys#xe as sysdba
SQL*Plus: Release 11.2.0.2.0 Production on Ned Vel 3 18:02:32 2019
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Enter password:
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
SQL> drop user mdp cascade;
User dropped.
SQL>
Pretend we're now on another computer; first, I'm going to create the MDP user:
SQL> show user
USER is "SYS"
SQL> create user mdp identified by test
2 default tablespace users
3 temporary tablespace temp
4 quota unlimited on users;
User created.
SQL> grant create session to mdp;
Grant succeeded.
SQL>
Back to operating system command prompt as I'm now going to import DMP file's contents.
C:\>impdp system#xe directory=my_dir dumpfile=mdp.dmp logfile=mdp_imp.log
Import: Release 11.2.0.2.0 - Production on Ned Vel 3 18:09:47 2019
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Password:
Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_FULL_01": system/********#xe directory=my_dir dumpfile=mdp.dmp logfile=mdp_imp.log
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "MDP"."TEST" 5.031 KB 5 rows
Processing object type SCHEMA_EXPORT/VIEW/VIEW
Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at 18:09:51
C:\>
Import has finished successfully. Now I can use the MDP user with all its objects, e.g.
C:\>sqlplus mdp/test#xe
SQL*Plus: Release 11.2.0.2.0 Production on Ned Vel 3 18:12:52 2019
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
SQL> select * from v_test;
ID
----------
1
2
3
4
5
SQL>
Don't forget what I said in another topic: grant MPD only privileges it needs. Currently, it can only create session and use existing objects, but can't create anything.
That's how it goes, more or less. Don't rely too much on GUI (you know how it is; those who live by the GUI, die by the GUI), clicking here and clicking there, hoping that something good will happen. Most probably won't. Though, once you know what you're doing, GUI is really a great help.

Why is it impossible to drop user despite it exists in dba_users view

I try to drop/alter user like this
drop user AVASILIEV_AXIOM_10X
And I get the following error
SQL> drop user AVASILIEV_AXIOM_10X;
drop user AVASILIEV_AXIOM_10X
*
ERROR at line 1:
ORA-01918: user 'AVASILIEV_AXIOM_10X' does not exist
But this user exists in the dba_users view:
SQL> select username from dba_users where username='AVASILIEV_AXIOM_10X';
USERNAME
------------------------------
AVASILIEV_AXIOM_10X
SQL>
Also, I can't create user with the same name because it already exists in the DB. What's the problem?
My Oracle version:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE 11.2.0.4.0 Production"
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
This is old thread but for reference Oracle Doc ID 1297361.1 suggests as follows:
SQL> drop user ahong3;
drop user ahong3
*
ERROR at line 1:
ORA-01918: user 'AHONG3' does not exist
SQL> select username from dba_users where username='ahong3';
USERNAME
------------------------------
ahong3
SQL> execute hcheck.full
HCheck Version 8i-11/1.95
Found 0 potential problems and 0 warnings
PL/SQL procedure successfully completed.
CAUSE
User was created forcibly in lower case. Drop user considers the user to be in upper case, and hence can't find it.
Ex: below statement will force the creation of the user in lower case.
SQL> Create user "ahong3";
SOLUTION
Force the drop user statement to drop the user created in lower case by specifying the user name in double quotes:
SQL> Drop user "ahong3";
This solution worked for me
DROP USER user CASCADE;
Hope this work cz its work for me

Oracle 12.1.0.2.0 - User creation successful but connection with new user fails

D:\app\Administrator\product\12.1.0\dbhome_1\BIN>sqlplus / as sysdba
SQL*Plus: Release 12.1.0.2.0 Production on Thu Oct 30 12:51:12 2014
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to: Oracle Database 12c Enterprise Edition Release
12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL> CREATE USER johndoe IDENTIFIED BY johndoe
2 DEFAULT TABLESPACE "USERS"
3 TEMPORARY TABLESPACE "TEMP";
CREATE USER johndoe IDENTIFIED BY johndoe
* ERROR at line 1: ORA-65096: invalid common user or role name
SQL> alter session set container=PDBORCL;
Session altered.
SQL> CREATE USER johndoe IDENTIFIED BY johndoe
2 DEFAULT TABLESPACE "USERS"
3 TEMPORARY TABLESPACE "TEMP";
User created.
SQL> GRANT CREATE SESSION TO johndoe;
Grant succeeded.
SQL> connect johndoe/johndoe ERROR: ORA-01017: invalid
username/password; logon denied
Warning: You are no longer connected to ORACLE. SQL>
Can Anyone please help?
connect johndoe/johndoe
This is wrong, you need to specify the pluggable database PDBORCL.
connect johndoe#pdborcl/johndoe
Here is a test case to prove,
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL> alter session set container=PDBORCL;
Session altered.
SQL> create user test identified by test;
User created.
SQL> grant create session to test;
Grant succeeded.
SQL> connect test#pdborcl/test;
Connected.
SQL>
You can have a look at Mandatory steps post 12c installation for common issues post 12c installation.

Resources