Get owner of the current view in Oracle - oracle

I want to create a view that containt a column which refers to the owner of this view. Something like that:
create or replace view scott.owner_v
as
select something() owner from dual;
Note: something() shouldn't necessary be a function or package reference. It can be anything that gives a desired output.
So querying select owner from scott.owner_v under JEREMY user, for example, would return SCOTT and when I compile such view in HR schema I get HR in owner column.
Maybe seems dumb to query SCOTT.owner_v to get SCOTT but I need it in terms of building DWH referring to different sources which are situated in different schemas. So then I would build dynamically a new view which is on a "higher" level that collects data from all schemas with extra column like owner which shows a source of data. I can put this column when building this "higher" view but I want to keep it as simple as it can be.
Obviously, I tried to place into a view the following parameters
sys_context('USERENV','CURRENT_USER')
sys_context('USERENV','CURRENT_SCHEMA')
user
but it refers to current logged user not to owner of the view.
Any help appreciated.

Just create local functions which returns own schemas in all schemas where do you want to create views:
create or replace function local_obj_owner return varchar2 as
begin
return $$PLSQL_UNIT_OWNER;
end;
/
Then add it into your views:
create view test_view as
select
local_obj_owner as view_owner,
dummy
from dual;

Try
select owner from all_views where view_name = 'OWNER_V';
and/or some alternatives (USER_VIEWS, DBA_VIEWS, ALL_OBJECS, ...).

Related

DB2- how to prevent user viewing view DDL

i'm having this situation whereby user are using Dbeaver to access to DB2. There is some views created. At the moment user have the ability to use the Dbeaver to see the view DDL (back end code).
Question : how/is there any way to prevent the user see the view DDL?
much appreciate you advice
Look at the Db2 Obfuscation facility.
CALL DBMS_DDL.CREATE_WRAPPED ('CREATE OR REPLACE VIEW TEST_OBFUSCATED AS SELECT TABNAME FROM SYSCAT.TABLES WHERE TABSCHEMA LIKE ''SYS%''');
SELECT TEXT
FROM SYSCAT.VIEWS
WHERE VIEWSCHEMA = CURRENT SCHEMA AND VIEWNAME = 'TEST_OBFUSCATED';
TEXT
CREATE OR REPLACE VIEW TEST_OBFUSCATED WRAPPED SQL11014 long_meaningless_string
You may use this view as any other one in the same way, but its text is not visible for everyone.
Moreover, you can use this "strange" obfuscated statement to create the view from scratch. There is a scalar function which helps you to get this obfuscated statement without creation it first.
VALUES DBMS_DDL.WRAP ('CREATE OR REPLACE VIEW TEST_OBFUSCATED AS SELECT TABNAME FROM SYSCAT.TABLES WHERE TABSCHEMA LIKE ''SYS%''')
If someone still needs to view the real view text, you may use Row and column access control (RCAC) on the SYSIBM.SYSVIEWS table.
If you want your users to be able to select from a view, they must be able to obtain the definition of that view.
You can wrap the query against the view in a set-returning user-defined function, which has all privileges of its creator, presumably a DBA, and grant other users only the EXECUTE privilege on that function. You will then be able to revoke from your users the privileges to read system catalog tables that you don't want them to read.
Details in the manual.

Oracle: why I can't select from VIEW using <SCHEMA_NAME>.<VIEW_NAME>?

There are some changes on the core product on which I'm working and some tables become now views and they are not working anymore because a view cannot be referenced with the schema name in front.
For example, the below will return an error: ORA-00942: table or view does not exist
select * from my_schema.my_view;
while a direct select from the view works fine
select * from my_view;
In case of a table, both scenarios above are working fine, is just the view that doesn't accept schema_name in front.
Why is that? Are there any decent workarounds?
EDIT: the selects are executed with my_schema user
Thanks all for your help, especially #mathguy.
Basically the problem was that my_view was in fact a public synonym for my_view_r which was the actual view and being public, you cannot call it using the schema name in front like I was trying. eg:
select * from my_schema.my_view;
Maybe it will be helpful for others that are facing this issue in the future, the workaround would be to create a private synonym to the same view (my_view_r) using the schema name like below:
create synonym my_schema.my_view for my_view_r;
This is the only way to call a synonym using the schema name.
It's a grant issue.
grant all on my_view to my_schema
Make sure your schema really is the owner by running:
Select * from all_objects where object_name = 'my_view';
I have a view stvytro with owner baninst1. There is a public synonym of the same name. The following both work:
select * from STVYTRO;
select * from baninst1.stvytro;

How to know whether the created view is valid or not

I am new to db.
Lets say I have created a view with force.
So how can I get know whether the view created is invalid or not?
I mean are there any queries from which I can get to know the validity status of the view?
Thanks.
You can use Oracle dictionary view user_objects:
select object_name, status from user_objects
where object_type = 'VIEW' and object_name = 'YOUR_VIEW';
If the table on which the view is based is altered for any reason, you may have to recompile the view. For example, if a table’s structure is altered, such as by a change to a column’s datatype, or perhaps if a column is dropped from the table altogether - a column that is used
by the view — then it may change the status of the view to 'INVALID'.
Also note that there are there versions of "all objects" view:
USER_OBJECTS - all objects owned by a current user;
ALL_OBJECTS - all objects on which a current user has any privileges;
DBA_OBJECTS - all database objects (you would need special privileges to access this view)
ALL_ and DBA_ versions have an additional column OWNER containing the owner of the object.
These "naming rules" are applied to the different Oracle dictionary views: [USER_ | ALL_ | DBA_] [INDEXES | TABLES | VIEWS | etc]
Maybe this helps:
SELECT object_name,
status
FROM user_objects
WHERE object_type = 'VIEW';
or (for views in all schemas)
SELECT owner,
object_name,
status
FROM all_objects
WHERE object_type = 'VIEW';
Apart from checking the status about that new view in the dictionary, you can do:
select 1 from OWNER.MY_NEWLY_CREATED_VIEW;
or
select count(*) from OWNER.MY_NEWLY_CREATED_VIEW;
Whatever the statement of your new view, from that feedback you know it works or not.
Oracle docs include the following as a way to update or find out if a view is invalid:
Recompile the view e.g. customer_ro via the following statement:
ALTER VIEW customer_ro
COMPILE;
If Oracle Database encounters no compilation errors while recompiling customer_ro, then customer_ro becomes valid. If recompiling results in compilation errors, then the database returns an error and customer_ro remains invalid.

How to get information about a User-Defined Type?

In simplicity, PL/SQL generally follow the following:
DECLARE
Variable declaration
BEGIN
Program Execution
EXCEPTION
Exception handling
END;
I am quite new to PL/SQL and i am looking at the variable declaration section where i would like to find out more information on SALES_PRODUCT_TY_LIST.
Is there a table i may look up to check on information on SALES_PRODUCT_TY_LIST, such as checking out table column information from all_tab_cols view?
CREATE OR REPLACE PROCEDURE GET_DISCOUNTS
(
v_have_list SALES_PRODUCT_TY_LIST
)
IS
QUERY VARCHAR(5000);
...
Thanks.
The Oracle database has an extensive data dictionary (what some other DBMS products call the INFORMATION SCHEMA). You can find all the views here. Alas, the revised ToC structure makes it harder to find something in the 11g documentation unless you already know what you're looking for, so use the index instead. 8-)
Anyway, the views you need to query are ALL_TYPES and ALL_TYPE_ATTRS.
This seems to be user defined collection type. You can find some information about it querying all_types/user_types view:
select * from user_types where type_name = 'SALES_PRODUCT_TY_LIST'
The definition of the type can be found for example by querying all_source/user_source view:
select text from user_source where name = 'SALES_PRODUCT_TY_LIST' order by line
Try this to get DDL:
SELECT dbms_log.substr(dbms_metadata.get_ddl('TYPE', 'SALES_PRODUCT_TY_LIST'), 32767,1)
FROM DUAL;
see: http://www.myoracleguide.com/s/gen_schema.htm
Ok i found something:
select *
from all_objects
where object_name like 'SALES%';

Oracle 9i: Synonymed Table Does Not Exist?

I've created a package that contains a stored procedure that I plan to invoke from a separate application. The stored procedure will return a sorted list of all the views and tables in the schema. To do that, it performs a simple select on the DBA_TABLES and DBA_VIEWS synonyms, as shown below:
CREATE OR REPLACE
PACKAGE BODY TITAN_ENTITY AS
PROCEDURE GETSCHEMAOBJECTS (RESULTS IN OUT T_CURSOR)
IS
V_CURSOR T_CURSOR;
BEGIN
OPEN V_CURSOR FOR
SELECT 'T' OBJECTTYPE, TABLE_NAME OBJECTNAME
FROM DBA_TABLES
WHERE OWNER = 'SONAR5'
UNION ALL
SELECT 'V' OBJECTTYPE, VIEW_NAME OBJECTNAME
FROM DBA_VIEWS
WHERE OWNER = 'SONAR5'
ORDER BY OBJECTNAME;
RESULTS := V_CURSOR;
END GETSCHEMAOBJECTS;
END TITAN_ENTITY;
I have verified that the synonyms in question exist, and are public:
CREATE PUBLIC SYNONYM "DBA_TABLES" FOR "SYS"."DBA_TABLES"
CREATE PUBLIC SYNONYM "DBA_VIEWS" FOR "SYS"."DBA_VIEWS"
My understanding is that, because they are public, I don't need any further permissions to get to them. If that understanding is incorrect, I wish someone would disabuse me of the notion and point me to more accurate data.
Now here's my problem: I can open a worksheet in Oracle SQL Developer and select from these tables just fine. I get meaningful data just fine (567 rows, as a matter of fact). But when I try to execute the stored procedure, Oracle complains with a compilation error, as shown below:
Error(9,8): PL/SQL: SQL Statement ignored
Error(10,16): PL/SQL: ORA-00942: table or view does not exist
When I double-click on that second error message, SQL Developer takes me to the first FROM clause ("FROM DBA_TABLES").
So I'm fairly stumped. I know SQL Server pretty well, and I'm new to Oracle, so please bear with me. If you could provide some clues, or point me in the right direction, I'd really appreciate it.
Thanks in advance!
Use ALL_TABLES and ALL_VIEWS instead of DBA_TABLES and DBA_VIEWS. ALL_% views should be accessible to all users.
If you select from a table or a view in a stored PL/SQL-procedure or a stored PL/SQL-function you need a direct grant. A grant via a database role isn't enough.
You probably need a direct grant on view dba_tables. (public) synonyms are just (public) synonyms. You need directly granted select rights.
See here: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:48704116042682#48798240264807
Edit: Sorry, I glossed over the part where you seem to say that you can select from DBA_TABLES directly. Most likely the issue is that your privileges are granted through a role as someone else answered. But it's still worth explaining that your understanding of PUBLIC synonyms is incomplete, and that using ALL_TABLES would be better if it accomplishes what you need.
The synonym being PUBLIC only means that all users can reference the synonym; it does not grant them any access to the object that the synonym refers to.
What you would do to most directly solve this error is grant SELECT privilege on the SYS views to the user(s) that will run this procedure. However, I think that is a very bad idea.
As suggested by Raimonds, consider whether you can get what you need from USER_TABLES or ALL_TABLES instead. What user is calling this procedure, and what access does that user have to SONAR5's tables?
Generally, if your application is interested in a table, presumably it has some privileges on it, in which case is should be listed in ALL_TABLES.

Resources