Let's say that my database has the following objects:
A table on schema "B" named "mlb_players"
A view on schema "C" named "mlb_players" that is a SELECT against a table on server "DB2"
A synonym on schema "D" named "mlb_players" that points to a table on server "DB3"
All of these objects are granted to my schema "RedSoxRule"
If I execute this query, from where would the data be retrieved?
SELECT *
FROM mlb_players
In other words, if a given name (in this case "mlb_players") is applicable to different object types, and the GRANTS are equal, in what order will Oracle find the requested object?
Oracle has a nice long explanation of this.
Basically, when resolving a name, it looks:
For objects in your schema with that name
For public synonyms with that name
If the name has multiple parts (e.g. C.mlb_players, it checks to see if the first part is a qualifying schema that you have access to.
In your example, Oracle won't find any of them. They're all in different schemas from your RedSoxRule schema, none of them are public synonyms, and you didn't qualify mlb_players with a schema name.
It doesn't actually matter what the type of the object is (table, view, synonym, package, etc) - they're all treated the same.
If I execute this query, from where would the data be retrieved
Nowhere. REDSOXRULE has no object called mlb_players so the query would fail with ORA-00942: table or view does not exist.
You would need to prefix the table name with the schema you're prefixing, e.g.
SELECT *
FROM d.mlb_players;
Let's suppose you have a variation on your posted structure.
REDSOXRULE has a view mlb_players for a.mlb_players. The query select * from mlb_players would select from this view, i.e from a.mlb_players.
Instead of a view REDSOXRULE has a private synonym mlb_players for b.mlb_players. The query select * from mlb_players would select from this synonym, i.e from b.mlb_players. Note that you can't have a private synonym with the same name as a table or view in your schema.
Instead of a private synonym the database has a public synonym mlb_players for d.mlb_players. The query select * from mlb_players would select from this publicsynonym, i.e from d.mlb_players.
That is, Oracle looks first for objects owned by the schema (tables, views, private synonyms, etc). Then it looks at public synonyms. Then it looks for objects in other schemas
Related
We are using JDBC DatabaseMetadata to discover objects in the database. DatabaseMetadata.getColumns returns more verbose information -that we really need- than those from select * from table where 1 = 2.
Now when I pass the table name -that is a reserved word in Oracle- to getColumns, it fails. If I escape the table name, it does not get results -as it doesn't see a table with that name (i.e. pass the table name "USER" instead of USER).
Is there a possible way to pass such table -named after reserved words to getColumns for Oracle database.
If I have a table sch1.tab1 is it possible to call it from schema/user sch2 just with
select * from tab1 (assume that we have all the privilegies)?
I am aware that in postgresql you can set the search path where db would look for tables which enables you to omit the schema when you are referencing a table but I do not know if this exists in oracle.
Thank you.
You can create a synonym, but you'd have to make one for each table you wanted to access; from sch2:
create synonym tab1 for sch1.tab1;
A more general method is to switch your current schema:
alter session set current_schema = 'SCH1';
You're still connected with your original user account and only have those privileges still, but you don't have to qualify objects in that schema any more. But now you would have to qualify any of your own tables (back in sch2), if you have objects in both schemas.
i have a table t1 in database A and another table t2 in another database B.
how can we select data from them without using qualifiers directly..
just as database1.table1.something.
You should be able to query it with fully qualified names such as SCHEMA.TABLE#DBLINK.
If you don't want to use the #DBLINK notation while querying from database A you can mask the #DBLINK in a view (In database A) and query that view instead.
CREATE OR REPLACE VIEW remote_table [(column_list)]
AS select * FROM SCHEMA.TABLE#DBLINK;
Now that I've learned about the concept of schema objects in Oracle and its order when matching the tables names.
For a sql query issued by user XYZ and accessing FOO_TABLE the order of preference would be to check
User table: XYZ.FOO_TABLE
User synonym: XYZ.FOO_TABLE
Public synonym: PUBLIC.FOO_TABLE
Looking at the following data of a view in XML:
<ROW>
<OWNER>XYZ</OWNER>
<VIEW_NAME>BAR_VIEW</VIEW_NAME>
<TEXT_LENGTH>...</TEXT_LENGTH>
<TEXT>
SELECT *
FROM SOME_NAME
</TEXT>
<EDITIONING_VIEW>N</EDITIONING_VIEW>
<READ_ONLY>N</READ_ONLY>
</ROW>
If I want to find the owner of SOME_TABLE, can I just start looking at the following order?
User table: XYZ.SOME_NAME
User synonym: XYZ.SOME_NAME
Public synonym: PUBLIC.SOME_NAME
Best,
Will
You're statement can actually be simplified somewhat, to:
User object: XYZ.SOME_TABLE
Public synonym: PUBLIC.SOME_TABLE
This rule applies to all database object (tables, packages, etc.). The local synonym step isn't required because 1) it is a local object and 2) Oracle doesn't allow for a name conflict between local objects (i.e. you can't have a synonym and a table in one schema with the same name).
The only qualifier here is that if the view definition contains the schema (SELECT * FROM SOME_SCHEMA.SOME_TABLE) or a database link (SELECT * FROM SOME_TABLE#SOME_DB_LINK) then the name resolution is done from the indicated schema (in the case of a DB link, from the schema indicated in the DB link's definition).
I have a view that is built on multiple tables from different users schema. By virtue of the currently logged in user, he is able to see the table from different schema. When the view is created the table name becomes ambiguous as the user have access to the same tables from the different schema.
Is there any way to specify to use the table from current user schema while creating the view?
Can we do it for one of the tables from the view definition while other tables can be selected from any schema?
"When the view is created the table
name becomes ambiguous as the user
have access to the same tables from
the different schema"
It isn't ambiguous to Oracle.
The view exists in a schema, SCHEMA_1. If that view refers to an object TABLE_A, Oracle will first look for an object TABLE_A in SCHEMA_1. If it finds a table, it will use that. If it finds a SYNONYM it will use whatever the synonym points to. If there is nothing in SCHEMA_1, it will look for a PUBLIC SYNONYM for TABLE_A and use whatever that points to.
SYNONYMS can point to other synonyms, views or tables.
You can query USER_DEPENDENCIES to see what objects the view is actually based on.
You cannot have a view in SCHEMA_1 that uses TABLE_A in SCHEMA_2 if queried from SCHEMA_2 but uses a different TABLE_A in SCHEMA_3 if queried from SCHEMA_3.
You should be able to access schema (with correct permissions) by prefixing the schema name.
schemaname.tablename
Hope I understood your question correctly.