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

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.

Related

Where is this Oracle object?

I have some SQL scripts; one of them references an object called "names". I can:
select * from names
and it returns results. However, I cannot see a table called "names". Neither can I see a view called "names". I can't find a custom type called "names".
If I look for one of the columns that is returned by the query select * from names using:
select * from sys.all_tab_columns where column_name like '%MyColumn%'
it finds a table called LSNAMES, but that has no rows.
Any ideas how I can find this "table"?
I'd start the research with understanding what type of object this is:
SELECT owner, object_name, object_type
FROM all_objects
WHERE object_name = 'NAMES'
Once you have a type, you could query some more information from all_<type>s
Look for:
A materialized view called NAMES
SELECT * FROM ALL_MVIEWS WHERE MVIEW_NAME = 'NAMES';
A synonym called NAMES
SELECT * FROM ALL_SYNONYMS WHERE SYNONYM_NAME = 'NAMES';

How to list indexes on materialized views (Oracle)

Am I correct to think that listing indexes for materialized views is the same as listing indexes for tables? In other words:
select *
from ALL_IND_COLUMNS
where TABLE_OWNER='SOME_OWNER'
and TABLE_NAME='SOME_TABLE'
order by INDEX_NAME, COLUMN_POSITION;
It is, yes.
When you create a materialized view, you are actually creating a table of the same name as well. If you look at ALL_OBJECTS, you'll see both a table and a materialized view with the same name
SELECT owner, object_name, object_type
FROM all_objects
WHERE owner = 'SOME_OWNER'
AND object_name = 'SOME_TABLE'

oracle table_privileges values

Does anybody know the values that are given in the table_privileges? I already found out what "A" means. But I did not find out for what the "S" stands for. I think this isnt documented. It has something to do with update privileges on particular columns.
The thing you are missing is that we can grant UPDATE on a subset of a table's columns.
First of all, let's just grant SELECT on a table. The value of UPDATE_PRIV is 'N', for None:
SQL> grant select on t23 to mr_x;
Grant succeeded.
SQL> select select_priv, update_priv
2 from table_privileges
3 where table_name = 'T23'
4 /
S U
- -
Y N
SQL>
Now, if I grant UPDATE on a single column the value of UPDATE_PRIV is 'S', presumably for Some:
SQL> grant update (col2) on t23 to mr_x
2 /
Grant succeeded.
SQL> select select_priv, update_priv
2 from table_privileges
3 where table_name = 'T23'
4 /
S U
- -
Y S
SQL>
Finally, I grant UPDATE on the whole table the value of UPDATE_PRIV is 'A', for All:
SQL> grant update on t23 to mr_x
2 /
Grant succeeded.
SQL> select select_priv, update_priv
2 from table_privileges
3 where table_name = 'T23'
4 /
S U
- -
Y A
SQL>
I'm sorry but having noticed an answer that #JustinCave gave to this very question back in 2005 I have to post it.
From the SQL Reference documentation on table_privileges
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96536/ch2486.htm#1318903
"TABLE_PRIVILEGES contains information on grants on objects for which
the user is the grantor, grantee, or owner, or PUBLIC is the grantee.
This view is included for compatibility with Oracle version 6. Oracle
Corporation recommends that you do not use this view."
Given that Oracle recommends you not use this view, I would strongly
suggest that you use the DBA_TAB_PRIVS view instead. The information
there should be a bit easier to decipher.

Managing Oracle Synonyms

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".

How can I find the OWNER of an object in Oracle?

I want to find the foreign keys of a table but there may be more than one user / schema with a table with the same name. How can I find the one that the currently logged user is seeing? Is there a function that gives its owner? What if there are public synonyms?
You can query the ALL_OBJECTS view:
select owner
, object_name
, object_type
from ALL_OBJECTS
where object_name = 'FOO'
To find synonyms:
select *
from ALL_SYNONYMS
where synonym_name = 'FOO'
Just to clarify, if a user user's SQL statement references an object name with no schema qualification (e.g. 'FOO'), Oracle FIRST checks the user's schema for an object of that name (including synonyms in that user's schema). If Oracle can't resolve the reference from the user's schema, Oracle then checks for a public synonym.
If you are looking specifically for constraints on a particular table_name:
select c.*
from all_constraints c
where c.table_name = 'FOO'
union all
select cs.*
from all_constraints cs
join all_synonyms s
on (s.table_name = cs.table_name
and s.table_owner = cs.owner
and s.synonym_name = 'FOO'
)
HTH
-- addendum:
If your user is granted access to the DBA_ views (e.g. if your user has been granted SELECT_CATALOG_ROLE), you can substitute 'DBA_' in place of 'ALL_' in the preceding SQL examples. The ALL_x views only show objects which you have been granted privileges. The DBA_x views will show all database objects, whether you have privileges on them or not.
I found this question as the top result while Googling how to find the owner of a table in Oracle, so I thought that I would contribute a table specific answer for others' convenience.
To find the owner of a specific table in an Oracle DB, use the following query:
select owner from ALL_TABLES where TABLE_NAME ='<MY-TABLE-NAME>';
Interesting question - I don't think there's any Oracle function that does this (almost like a "which" command in Unix), but you can get the resolution order for the name by:
select * from
(
select object_name objname, object_type, 'my object' details, 1 resolveOrder
from user_objects
where object_type not like 'SYNONYM'
union all
select synonym_name obj , 'my synonym', table_owner||'.'||table_name, 2 resolveOrder
from user_synonyms
union all
select synonym_name obj , 'public synonym', table_owner||'.'||table_name, 3 resolveOrder
from all_synonyms where owner = 'PUBLIC'
)
where objname like upper('&objOfInterest')
Oracle views like ALL_TABLES and ALL_CONSTRAINTS have an owner column, which you can use to restrict your query. There are also variants of these tables beginning with USER instead of ALL, which only list objects which can be accessed by the current user.
One of these views should help to solve your problem. They always worked fine for me for similar problems.
To find the name of the current user within an Oracle session, use the USER function.
Note that the owner of the constraint, the owner of the table containing the foreign key, and the owner of the referenced table may all be different. It sounds like it’s the table owner you’re interested in, in which case this should be close to what you want:
select Constraint_Name
from All_Constraints
where Table_Name = 'WHICHEVER_TABLE'
and Constraint_Type = 'R' and Owner = User;
It is like #entpnerd said, but I suggest you to use upper() clause:
select *
from ALL_TABLES
where upper(TABLE_NAME) = upper('<table_name>')

Resources