view with the tables from multiple user schema - oracle

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.

Related

Oracle SODA: collection created in a schema to be visible to another schema

I have a schema (owner_schema) that is able to create collections using SODA api PL/SQL. Now I want to have another schema (user_schema) to be able to access the collection created by the owner_schema and be able to insert/read/delete documents: The user_schema must not be the owner of the collections, and it must not have any CREATE privileges (CREATE_TABLE, etc.).
The problem is that even if user_schema has SODA_APP role, he cannot see collections created by owner_schema.
I have already tried to grant select over the backing table to user_schema, but it doesn't work (user_schema calls openCollection so I guess the grant must be over the collection, not the table). I see that querying the JSON$USER_COLLECTION_METADATA view the owner_schema see the collections, and user_schema has this view empty. Tried also to give grants over the COLLECTION_METADATA table to user_schema but no luck. I read about mapped collection but it suppose user_schema to run create_collection proc which needs CREATE_TABLE priv.
Is it possible for a schema to operate over collections created by another schema without owning it and without having any privileges like CREATE_TABLE?

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

GRANT INSERT on tables participating in an updateable view

The given database contains a masterdata (MD) Schema and an application specific Schema (APP). In the APP Schema we have a view which provides the applications data from one table in the scheme joined with data from the MD Schema.
Example: Think of an address book application, which holds an address table, but cities and ZIP codes are joined from a masterdata table in another Schema which is maintained centrally.
CREATE VIEW view_adress AS
SELECT app.ID, app.Street, app.ZIP, zip.CITYNAME
FROM APP.adress app
LEFT OUTER JOIN MD.zipcodes zip
ON app.ZIP = zip.ZIP
This is very simplified. The actual view I use is a lot more complicated like that and therefore I implemented an INSTEAD OF INSERT, UPDATE Trigger to map INSERTs on the view to the correct base table in my APP Schema.
The application users (role) is granted SELECT,INSERT,UPDATE,DELETE on all tables inside this APP Schema. They are also granted SELECT on that zipcode table in the master data Schema.
When I insert on that view, I get an "ORA-01720: Grant Option Does Not Exist"... I don't know the exact cause of this error, but it can be assumed that the INSTEAD-OF Trigger never INSERTS on the ZIP Code Table, only on the address table.
I understand, that granting the application users INSERT privilege on the zipcode table would probably resolve this issue, but I am feeling uncomfortable granting INSERTs on tables to users which they never should edit in any way, because these are only lookups.
Is there another, possibly "the correct way" to solve this?
By "insufficient permissions error" do you mean this?
ORA-01720: grant option does not exist for 'MD.ZIPCODES'
*Cause: A grant was being performed on a view or a view was being replaced
and the grant option was not present for an underlying object.
*Action: Obtain the grant option on all underlying objects of the view or
revoke existing grants on the view.
If so, the solution is that you need to grant the relevant permissions to the schema owning the view - not to the roles that use the view:
grant insert on md.zipcodes to app with grant option;
It's true that you are still having to grant a permission that is logically not required, but you are not granting it to users, only the app schema.

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.

Querying tables listed in DBA_Tables

A third party product we have at my company uses Oracle as a backend. I'm attempting to log into the Oracle database and look at the schema and data. I've logged in as sys/sysdba, created a user with a default tablespace of that created by the application, and granted the user all necessary permissions to query the structures. I've also set O7_DICTIONARY_ACCESSIBILITY to true to allow querying of the data dictionary objects.
After logging in as the user and querying User_Tables nothing is returned. But when I query DBA_Tables the tables I'd expect to find are returned. I'm new to Oracle so I'm not quite certain how a non-system table can be in the tablespace, but not a user_table.
More importantly, how do you query the data in these tables? Whenever I attempt a simple "Select *" from the tables I get a "table or view does not exist" error.
Thanks in advance.
The default tablespace you set for a user controls what tablespace objects owned by that user are created in. It has nothing to do with what objects they can query.
USER_TABLES returns information about the tables that a particular user owns. It does not sound like your user owns any tables, so you would expect that to be empty.
ALL_TABLES returns information about the tables that a particular user has access to. If you granted the appropriate privileges, your user should see the tables in this data dictionary view.
DBA_TABLES returns information about every table in the database even if you don't necessarily have access to the underlying table.
If you are trying to query data from one of the tables, are you specifying the schema name (the OWNER column in ALL_TABLES)? If you do not own an object, you generally need to use fully qualified names to reference it, i.e.
SELECT *
FROM schema_owner.table_name
You can avoid using fully qualified names if
You create a synonym (public or private) for the object
You change the CURRENT_SCHEMA for the session. This changes the default schema that a name is resolved under. It does not affect permissions and privileges. You can change the current schema with the command
ALTER SESSION SET current_schema = new_schema_name
You would have to do this for each session the user creates-- potentially in a login trigger.

Resources