Oracle views user - oracle

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

Related

ORA-00942: Table or View not exist connecting with another user

in Oracle SQL developer I got error ORA-00942: Table or View not exist connecting with another user when I do the following:
CREATE USER marta IDENTIFIED BY 'marta';
GRANT SELECT, INSERT ON myTable TO marta;
so then, executing:
CONNECT marta/marta;
INSERT INTO myTable VALUES ('1', 'foo', bar');
got the ORA-00942...
Obviusly, If I use system user I can insert row with no issues.
I searched other answers but I couldnt solve this... what is wrong
Obviusly, If I use system user I can insert row with no issues.
Uh-oh. There's nothing obvious about that. The SYSTEM user should not own a table called MY_TABLE (or whatever application table that is actually named). The SYSTEM user is part of the Oracle database, its schema is governed by Oracle and using it for our own application objects is really bad practice.
But it seems you have created a table in that schema and user MARTA can't see it. That's standard. By default users can only see their own objects. They can only see objects in other schemas if the object's owner (or a power user) grants privileges on that object to the other user.
So, as SYSTEM
grant select on my_table to marta;
Then, as MARTA
select * from system.my_table;
To avoid prefixing the owning schema MARTA can create a synonym:
create or replace synonym my_table for system.my_table;
select * from my_table;
But really, you need to stop using SYSTEM for your own tables.

In what order will Oracle use synonym, view, and table objects?

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

Reference a table in other schema omiting schema name

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.

How to create new schema and list all schema name in oracle

I want to create one new schema in oracle and I used sample code, which is available here
CREATE SCHEMA AUTHORIZATION oe
CREATE TABLE new_product
(color VARCHAR2(10) PRIMARY KEY, quantity NUMBER)
CREATE VIEW new_product_view
AS SELECT color, quantity FROM new_product WHERE color = 'RED'
GRANT select ON new_product_view TO scott
/
But, getting error
ERROR at line 1:
ORA-02421: missing or invalid schema authorization identifier
Also, Please help me how to list name of all available schema. I am using
select username from dba_users;
to list schema, but i think, its not a right approach, because, user and schema has many-to-many relation,which means I can't get all schema name here.
Please help me !!
From oracle documentation:
This statement does not actually create a schema. Oracle Database
automatically creates a schema when you create a user
So you first need to create a User with the schema name
As for your query it's fine, since username list is equal to schema names unavailable
UPDATE: I can't really test it now, but should be something like this:
CREATE USER oe IDENTIFIED BY oePSWRD;
CREATE SCHEMA AUTHORIZATION oe
CREATE TABLE new_product
(color VARCHAR2(10) PRIMARY KEY, quantity NUMBER)
CREATE VIEW new_product_view
AS SELECT color, quantity FROM new_product WHERE color = 'RED'
GRANT select ON new_product_view TO scott;
From the docs: http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_6014.htm
The schema name must be the same as your Oracle Database username.
Do you want to find all users, or all users for which a table (for example) exists? If the latter then ...
select distinct
owner
from
dba_tables
where
owner not in ('SYS','SYSTEM')
Add in other usernames that you're not interested in listing as required.

view with the tables from multiple user schema

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.

Resources