Managing Oracle Synonyms - oracle

I was reading this article:
Managing Oracle Synonyms
Regarding the order of preference, when it come to resolving an object name to the actual object, it says:
Local objects will always be accessed first.
If a local object does not exist, the object with a private synonym will be accessed.
If a private synonym does not exist or the object does not exist, then the public synonym will be used.
I was wondering if the public objects are missing in this order somehow?
E.g. if user BOB queries
select * from FOOBAR
and there is no BOB.FOOBAR in dba_tables/views but PUBLIC.FOOBAR.
Does Oracle resolve it to PUBLIC.FOOBAR or will it check for synonyms first?
Thank you.

In your example, FOOBAR is almost certainly a public synonym. There is no PUBLIC schema but PUBLIC is listed as the owner of a public synonym.
If I create a new public synonym
SQL> create public synonym pub_syn_emp
2 for scott.emp;
Synonym created.
the owner of that synonym ends up being PUBLIC
SQL> ed
Wrote file afiedt.buf
1 select object_name, owner, object_type
2 from dba_objects
3* where object_name = 'PUB_SYN_EMP'
SQL> /
OBJECT_NAME OWNER OBJECT_TYP
-------------------- ---------- ----------
PUB_SYN_EMP PUBLIC SYNONYM
In addition, item #3 does not appear to be correct. If there is a private synonym that points to a non-existent object and a public synonym that points to a valid object, the private synonym still takes precedence. You'll just get an error when Oracle tries to resolve the private synonym to an actual object.
SQL> create synonym syn_emp for scott.no_such_table;
Synonym created.
SQL> create public synonym syn_emp for scott.emp;
Synonym created.
SQL> select * from syn_emp;
select * from syn_emp
*
ERROR at line 1:
ORA-00980: synonym translation is no longer valid

At least up to 10g, PUBLIC is not a real user. You cannot create objects in the "Public schema":
SQL> CREATE TABLE public.foobar (id integer);
CREATE TABLE public.foobar (id integer)
ORA-00903: invalid table name
SQL> CREATE TABLE system.foobar (id integer);
Table created
SQL>
If you run this query:
SELECT object_name
FROM dba_objects
WHERE owner='PUBLIC'
AND object_type IN ('TABLE', 'VIEW');
You can answer the question about pre-defined tables/views in the PUBLIC "schema".

Related

Is there any way to find the base type of object for which the synonym is created in Oracle 12c?

CREATE SYNONYM office
FOR SEQ001;
I need some system table/any other way that gives me information that SEQ001 is sequence .
In short I need a query that enlist synonyms only created for synonym objects and no other objects.
That would be something like this:
SQL> create sequence seq001;
Sequence created.
SQL> create synonym syn_se for seq001;
Synonym created.
SQL> select s.synonym_name, o.object_name, o.object_type
2 from user_synonyms s join user_objects o on o.object_name = s.table_name;
SYNONYM_NAME OBJECT_NAME OBJECT_TYPE
--------------- --------------- -------------------
SYN_SE SEQ001 SEQUENCE
SQL>
Now, you can apply different filters to it, e.g. where o.object_type = 'SEQUENCE' to see only synonyms related to sequences.
To list all synonyms that reference other synonyms use the dictionary view ALL_SYNONYMS and check if the synonym definition correspond to an other synonym.
Example
The first synonym reference a sequence, the two other reference a synonym.
The query shows the two "nested" synonyms.
create sequence seq001;
create synonym syn001 for seq001;
create synonym syn002 for syn001;
create synonym syn003 for syn002;
select OWNER, SYNONYM_NAME
from all_synonyms
where (TABLE_OWNER, TABLE_NAME) in
(select OWNER, SYNONYM_NAME from all_synonyms)
;
OWNER SYNONYM_NAME
---------- ------------
OOO SYN002
OOO SYN003
The view ALL_SYNONYMS shows all synonyms that your user has a granted access. There is also a dictionary view DBA_SYNONYMS showing all existing synonyms, but you'll need extra privilege to access it.

altering Table Owner of multiple synonyms

I have 848 NONEDITIONABLE PUBLIC SYNONYM that have the TABLE_OWNER as Dev.
I want help to alter all these NONEDITIONABLE PUBLIC SYNONYM to Prod, but in order to do so we need to extract all the queries. Is there a query to do so?
current:
CREATE OR REPLACE NONEDITIONABLE PUBLIC SYNONYM "CONFIG_SEQ" FOR "Dev"."CONFIG_SEQ";
expected:
CREATE OR REPLACE NONEDITIONABLE PUBLIC SYNONYM "CONFIG_SEQ" FOR "Prod"."CONFIG_SEQ";
your time and help is appreciated.
Thank You
we need to extract all the queries. Is there a query to do so?
Yes. Generate the script from the data dictionary:
select 'CREATE OR REPLACE NONEDITIONABLE PUBLIC SYNONYM "'
|| synonym_name ||'" FOR "PROD"."' || table_name || '";'
from all_synonyms
where owner = 'PUBLIC'
and table_owner = 'DEV'
/
For future reference please remember that needing to do this is a failure of process. DDL scripts are just like any other code, and should be kept in a source control repository, and checked out and deployed through managed releases.

Create public synonyms for table and sequence in oracle

I need to create public synonyms for sequence.Could you please suggest how to create synonyms for sequence in oracle 11g.
Alter script to add constraint:
ALTER TABLE schema.table_name ADD( CONSTRAINT pk PRIMARY KEY(primaryKey_ID));
Sequence:
CREATE SEQUENCE table_name START WITH 1;
According to documentation you can create a public synonym for your sequence in the same way you do for a table:
create public synonym table_name for yourSchema.table_name;
create public synonym sequence_name for yourSchema.sequence_name;

Oracle synonym error from Hibernate

I am getting below error in my application.
org.hibernate.util.JDBCExceptionReporter -- ERROR -- ORA-00980: synonym translation is no longer valid
i have checked the synonym,that is valid.
Can anyone please help.
You may have the synonym in VALID status which refers to even non-existing object:
SQL> create synonym t_syn for abrakadabra;
Synonym created.
SQL> select status from user_objects where object_name = 'T_SYN';
STATUS
-------
VALID
SQL> select * from t_syn;
select * from t_syn
*
error in line 1:
ORA-00980: synonym translation is no longer valid
SQL> select status from user_objects where object_name = 'T_SYN';
STATUS
-------
VALID
So first of all you need to check the existance of the object the synonym refers to.

How to correctly make a public synonym

This is a pretty silly one, but I need help.
I have a table owned by mydbowner. It is named mydbowner.mytable. I tried to make a public synonym by issuing the command:
CREATE OR REPLACE PUBLIC SYNONYM mytable FOR mydbowner.mytable;
When I do this, and I query the table I get:
ORA-01775: looping chain of synonyms
How do I make this synonym without having the problem.
I think Justin is on the right track. What I think it actually means is that mydbowner.mytable doesn't exist.
Here's an example:
SQL> conn mbobak
Enter password:
Connected.
SQL> drop table mytable;
drop table mytable
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create public synonym mytable for mbobak.mytable;
Synonym created.
SQL> select * from mytable;
select * from mytable
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
I think what's happening is that Oracle tries to resolve mytable, there is no mytable in mbobak schema, so it looks for it in PUBLIC, it finds it, and sees that it points to mbobak.mytable. But, mbobak.mytable doesn't exist, so, it looks for mytable in PUBLIC, and there's the loop.
And in fact, if you create mytable, the error goes away:
SQL> create table mytable as select * from dual;
Table created.
SQL> select * from mytable;
D
-
X
1 row selected.
SQL> drop table mytable;
Table dropped.
SQL> select * from mytable;
select * from mytable
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
Yes, I realize that doesn't really entirely make sense, as, once the public synonym resolved to mbobak.mytable, and that's not found, it seems to me, it should return an error ORA-942 "table or view does not exist", which makes far more sense to me.
But, this does seem to be how it works.
QED
Hope that helps.
The error you're getting implies that mydbowner.mytable is not, in fact a table. What does
SELECT object_type
FROM all_objects
WHERE owner = 'MYDBOWNER'
AND object_name = 'MYTABLE'
return?

Resources