How to get parameters properties from a stored procedure in Oracle? - oracle

I am developing an admin panel where we can determine which stored procedures and views can be called in Oracle 12c schemas, from services in our micro-services platform.
The services must know which parameters a procedure needs, and which columns a view has available, in order to call them.
I the admin panel, the creator of the procedure or view may register it, by typing in these information, like object's name, each parameter's name, length and data type.
But it would be much more elegant if the user just types the name of the object and then a SQL SELECT would retrieve a procedure's parameters properties in a table, and the same with the view's column's properties, so the panel would register those configurations automatically.
Could anybody post a query on how to achieve this? I am very new to Oracle and I don't know how to query the objects metadata.

I believe your are looking for something like this.
SELECT *
FROM SYS.DBA_PROCEDURES
WHERE OBJECT_TYPE = 'PROCEDURE'
AND OBJECT_NAME = 'xxxx'
Once you have that, you can get the parameters from something like this.
SELECT *
FROM SYS.ALL_ARGUMENTS
where object_name = 'procedure_name';

This can be used for views (I used USER_... metadata views, but you can use DBA_... depending of user grants):
SELECT A.TABLE_NAME, A.COLUMN_NAME, A.DATA_TYPE
FROM USER_TAB_COLUMNS A
INNER JOIN USER_VIEWS B ON A.TABLE_NAME = B.VIEW_NAME
/* WHERE A.TABLE_NAME = 'xxxx' */
ORDER BY TABLE_NAME, COLUMN_ID;

Related

Is it possible to set default ORACLE dblink for session and avoid #dblink_name suffixes

I have an Oracle database with a couple of public dblinks for various customers. All linked databases for all customers are identical. Also I have a schema on my host machine only, where I stored DB views with some data retrieval logic.
Currently, if I want to retrieve the same data from various customers, I have to create separate almost identical views for every client:
CREATE VIEW my_view_for_cliet1 AS
SELECT *
FROM table1#dblink1;
CREATE VIEW my_view_for_cliet2 AS
SELECT *
FROM table1#dblink2
Is it possible to set default dblink for session (or something similar) and have only one DB view without explicit dblink, for example:
CREATE VIEW my_view AS
SELECT *
FROM table1;
-- below I want to retrieve data from 3rd client
ALTER SESSION SET DEFAULT DBLINK dblink3;
SELECT * FROM my_view;
P.S. I have only SELECT rights on linked machines so I can't create any views or other objects.
No, that is not possible. Every reference to a dblink must be explicit.
Note that each of the other solutions presented (so far) can give the appearance of what you're asking, but still require explicit dblink references in all of the actual views and thus the same DDL changes for every new link and/or client user. There's no way to avoid creating those individual views or explicit references at some level (which is what I believe you were asking), even if you hide them somewhat from the user.
I'd suggest using synonyms, and set up a procedure to change them all at once, e.g.
create or replace procedure SET_DBLINK ( target_link IN VARCHAR2 ) is
begin
execute immediate 'create or replace synonym TABLE1 for TABLE1#' || target_link;
execute immediate 'create or replace synonym TABLE2 for TABLE2#' || target_link;
-- ...etc...
end;
/
That way you could do:
exec SET_DBLINK('dblink3');
select * from table1;
You'd probably want to add validation and exception handling to the procedure, but I left it simple for readability.
For example, user manager
CREATE OR REPLACE VIEW manager.example1 (
column1,
column2
)
AS
select 1, user from dual#dblink1
where 'SCOTT'=user
union all
select 2, user from dual#dblink2
where 'MANAGER'=user
union all
select 3, user from dual#dblink3
where 'HR'=user;
grant select on example1 to scott;
grant select on example1 to hr;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
2 MANAGER
user scott
create synonym example1 for manager.example1;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
1 SCOTT
user hr
create synonym example1 for manager.example1;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
3 HR

How can I find the invisible table in oracle 11g?

There is a table named IM_RESULT_INFO. Because I can see it by SELECT * FROM IM_RESULT_INFO.
But it doesn't exist in table nor view lists in sqldeveloper. I also tested SELECT * FROM all_all_tables and SELECT * FROM dba_tables, and couldn't find the table.
In Eclipse IDE, I searched for it in whole project files, but the only code I found was SELECT ... FROM IM_RESULT_INFO.
I think it is a mixture of tables, but there's no way to analyze it. How can I find it?
It must be a synonym or a view, check the synonyms view to see what object is referenced by it:
SELECT *
FROM all_synonyms
WHERE synonym_name = 'IM_RESULT_INFO'
Or the views view:
SELECT *
FROM all_views
WHERE view_name = 'IM_RESULT_INFO'
You can check in ALL_OBJECTS if you are not sure about the type of an object. It will provide you the Types and other important details also.
For Materialized view please check ALL_MVIEWS.
SELECT *
FROM ALL_OBJECTS
WHERE OBJECT_NAME='IM_RESULT_INFO';

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 do I get all indices on a Table in Oracle via JDBC, even if they are owned by different users?

Yes, I know about DatabaseMetadata.getIndexInfo, but it doesn't seem to do what I want.
I've got two users/schemas, let's call them A and B.
There's a table in A called TAB. The user B created an index on A.TAB, let's call that index IND.
The information that I want is: what indices are there on the table TAB in the schema A (a.k.a with the owner A). I don't care about the owner of the indices, just that they are on that specific table.
Experimenting with getIndexInfo I found out the following things:
the first argument catalog seems to be entirely ignored by the Oracle JDBC driver.
the second argument schema restricts which table statistics is returned and the owner of the index
unique and approximate do (roughly) what they should (except that giving approximate=false will actually execute an update statistics statement).
Having traced the SQL the JDBC driver executes on getIndexInfo(null, "A", "TAB", false, true), I got this:
select null as table_cat,
owner as table_schem,
table_name,
0 as NON_UNIQUE,
null as index_qualifier,
null as index_name, 0 as type,
0 as ordinal_position, null as column_name,
null as asc_or_desc,
num_rows as cardinality,
blocks as pages,
null as filter_condition
from all_tables
where table_name = 'TAB'
and owner = 'A'
union
select null as table_cat,
i.owner as table_schem,
i.table_name,
decode (i.uniqueness, 'UNIQUE', 0, 1),
null as index_qualifier,
i.index_name,
1 as type,
c.column_position as ordinal_position,
c.column_name,
null as asc_or_desc,
i.distinct_keys as cardinality,
i.leaf_blocks as pages,
null as filter_condition
from all_indexes i, all_ind_columns c
where i.table_name = 'TAB'
and i.owner = 'A'
and i.index_name = c.index_name
and i.table_owner = c.table_owner
and i.table_name = c.table_name
and i.owner = c.index_owner
order by non_unique, type, index_name, ordinal_position
As you can see both table_name and i.owner are restricted to being TAB. This means that this query will only return index information that is owned by the same user as the table.
I can think of three possible workarounds:
always create the index and the table in the same schema (i.e. let them have the same owner). Unfortunately that's not always an option.
Query with schema set to null. This would get ugly as soon as two schemata contained the same table name (because there's no way to find out on which table (i.e. which table owner) a given schema is).
execute that SQL directly (using executeQuery()). I'd rather not fall down to this level, unless it's absolutely unavoidable.
None of those workarounds look particularly pleasing to me, but if nothing else works, I might have to fall back to direct SQL execution.
Both the Database and the JDBC Driver are at 11.2.0.2.0.
So basically my questions are:
Is this a bug in the JDBC driver, or is there some logic behind it that I'm unaware of?
Is there a simple and reasonably portable way to get Oracle to give me the information that I need?
I suggest you query directly the Oracle dictionary tables, BUT start with:
select * from dba_indexes
Using that view it should be almost trivial to get the info you need.
However, accesing the dba_ tables and views requires the user to have special privileges, but since you don't want to give DBA privilege to everyone, you can just:
grant select any dictionary to username
connected as system or sys so the selected user can query the dictionary.
Just in case you want to explore Oracle's dictionary, try:
select * from dict
Best regards.
always create the index and the table in the same schema (i.e. let them have the same owner). Unfortunately that's not always an option.
That would be my preferred way of doing it.
Query with schema set to null. This would get ugly as soon as two schemata contained the same table name (because there's no way to find out on which table (i.e. which table owner) a given schema is)
Of course you can find that out, because the result set returned by getIndexInfo() does contain the correct schema for each table. But you can't find out in which schema the index is.
execute that SQL directly
I would actually use a modified version of that query that also returns the schema for each index to alleviate the identification of the index.
But again: I would also create the index and the table in the same schema.

Finding Oracle stored procedures

Since I am new to Oracle, please tell me what different ways to find packages, stored procedures, triggers, functions, indexes, tablespaces
Thanks
The following statement gives you an overview of all database objects in the current user:
SELECT
object_name,
object_type
FROM
user_objects;
If you are searching for documentation, you can look at Morgan's Library
You can download Oracle SQL Developer free. This allows you to explore all the objects in your database via a simple interface.
I shall walk you through the different shades of "all_object":
SQL> show user
USER is "C##SCOTT"
SQL>
Getting all the types of object:
select distinct object_type from all_objects;
EDITION
CONSUMER GROUP
SEQUENCE
SCHEDULE
PROCEDURE
OPERATOR
DESTINATION
WINDOW
SCHEDULER GROUP
PACKAGE
PROGRAM
LOB
XML SCHEMA
JAVA RESOURCE
JOB CLASS
DIRECTORY
TABLE
SYNONYM
INDEX
VIEW
FUNCTION
INDEXTYPE
JAVA CLASS
TYPE
EVALUATION CONTEXT
25 rows selected.
Now, you can zoom down to the "TABLE" type of object:
select object_name||','||object_id||','||owner from all_objects where object_type='TABLE' ;
Or all the objects of an owner:
select object_name||','||object_id||','||OBJECT_TYPE from all_objects where owner = 'SYS';
Trust me, you will learn more this way - anyone can click through any GUI tool, but to issue the SQL command, you will need some knowledge.

Resources