Finding Oracle stored procedures - oracle

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.

Related

Oracle - using synonym as variable

i need to use synonym as variable in a block. I have 2 different schemas with same tables on them and job that switches between schemas making one active. Now I want to write a block checking which schema is active with ALL_SYNONYMS and using result as part of a query.
Here is example:
DECLARE
OWNER VARCHAR2(15);
BEGIN
SELECT TABLE_OWNER
INTO OWNER
FROM ALL_SYNONYMS
WHERE TABLE_NAME = 'MY_TABLE1';
SELECT *
FROM OWNER.MY_TABLE2 ;
END;
But I’m getting ORA-06550 table or view does not exist, and when i run query itself where i put value from ALL_SYNONYMS it returns result.
Any idea how to fix this?
Thanks
You are attempting using symptoms incorrectly. Synonyms are used so you do not need to know which is active. According to the documentation:
Synonyms provide both data independence and location transparency.
Synonyms permit applications to function without modification
regardless of which user owns the table or view and regardless of
which database holds the table or view.
You just use the synonym instead of the object itself.
create table evens( id integer generated always as identity
, val integer
) ;
create table odds( id integer generated always as identity
, val integer
) ;
insert all
when mod(val,2) = 0 then into evens(val)
when mod(val,2) = 1 then into odds(val)
select level val
from dual connect by level <= 10;
-- create the synonym then use it in Select;
create or replace synonym current_even_odd for evens;
select * from current_even_odd;
-- now change the synonym, then run the EXACT same query.
create or replace synonym current_even_odd for odds;
select * from current_even_odd;
In this case it is not quite without modification, you need to change the synonym, But it seems you are trying that already.
Note: You cannot create a synonym for a schema but must point it to a specific object.
I attempted a db<>fiddle for the above, but it appears it is having problems at the moment.
I agree with Belayer that the synonym should provide a layer of abstraction on your tables and your procedure shouldn't need to know what the schema is. But the "table or view does not exist" error is likely an issue related to privileges and definer's rights versus invoker's rights.
To directly reference an object in a procedure, the procedure's schema must have a direct grant to the table. However, an ad hoc query only needs a role with privileges on the object. This is why the SQL will work in your IDE but not in the procedure. Ensure the code that modifies objects and switches synonyms is granting privileges to both roles and directly to schemas.
If direct grants are not possible, you will need to modify the procedure to use AUTHID CURRENT_USER and change the SQL statements to use dynamic SQL - which can be a huge pain. For example:
create or replace procedure test_procedure authid current_user is
v_count number;
begin
execute immediate
q'[
select count(*)
from some_table
]'
into v_count;
end test_procedure;
/
If you really do need to manually switch between schemas, then you may want to consider using something like execute immediate 'alter session set current_schema=schema1'; in the procedure and using dynamic SQL for all of the querying.

How to know if a db-link is used somewhere in a DB

I would like to know if it exists an Oracle command to know if a DB-LINK (name: myBDLink) is used somewhere in a DB and how to display the objects (views,materialized views, procedures, functions, ...) which use it.
Could you please help me with that ?
Thanks for your help
Well, you could try to query various system views and see whether any of them contains a string you're looking for. As you want to check the whole database, you'll probably connect as a privileged user and check dba_ views; otherwise, all_ or user_ would do.
For example, to check procedures, functions, packages, ...:
select owner, name, type, line
from dba_source
where owner not in ('SYS', 'SYSTEM')
and lower(text) like '%mydblink%';
To check views, you'll need a function which will search through its LONG datatype column (as you can't use it directly in SQL):
create or replace function f_long(par_view in varchar2, par_String in varchar2)
return varchar2
is
l_text varchar2(32000);
begin
select text
into l_text
from dba_views
where owner not in ('SYS', 'SYSTEM')
and view_name = par_view;
return case when instr(lower(l_text), lower(par_string)) > 0 then 1
else 0
end;
end;
/
and then
select owner, view_name
from dba_views
where f_long(view_name, 'mydblink') = 1;
I excluded SYS and SYSTEM as they should not contain anything of users' stuff. Perhaps you'd want to exclude some more users.
To see some more (re)sources, query the dictionary, e.g.
select table_name, comments
from dictionary;
TABLE_NAME COMMENTS
------------------------------ --------------------------------------------------
USER_CONS_COLUMNS Information about accessible columns in constraint
definitions
ALL_CONS_COLUMNS Information about accessible columns in constraint
definitions
DBA_CONS_COLUMNS Information about accessible columns in constraint
definitions
<snip>
There is no complete answer. How would the database know of code that is outside of the database? It can't. So if you have a sql script, or some application that does not rely on stored procedures to do everything, the database will not know of them.
That said, for dependencies that are in stored procedures in the database, you can try this:
select *
from dba_dependencies
where referenced_link_name is not null
;
To add to the other (correct) answers that have been posted by #Littlefoot and #EdStevens, a quick-and-dirty analysis can also be made against the Automated Workload Repository (AWR).
The benefit of this approach is it will find usages of remote objects from SQL submitted to the database whether that SQL is in DBA_SOURCE or not (e.g., is embedded in an external application).
-- Find any objects referenced across a database link (sort of)
select object_node, object_name, count(distinct sql_id) sql_id_count
from dba_hist_sql_plan
where object_type = 'REMOTE'
group by object_node, object_name
order by object_node, object_name
;
The problem is that AWR data isn't 100% complete. First of all, it's not kept around forever, so a database link last used more than a month (or two months or however long your DBAs keep AWR data for) wouldn't be seen. Second of all, AWR only takes snapshots periodically, say every hour. So it's theoretically possible for a SQL to use a database link and then get aged out of the library cache before the next AWR snapshot.
I think the chance of missing something due to that last bit is small on the systems I work with. But, if you have poorly written applications (i.e., no bind variables) and limited shared pool space, it's something to worry about.

List all procedures along with the tables and columns used in that procedure in Oracle

Last night got a call from my team lead and he asked me to make the list of all the procedures along with the tables and columns used in Oracle.
I got a query to list all the procedures along with tables and dblink but couldn't get column names (along with DML if possible) used in that Procedure :
select DISTINCT OWNER, NAME, referenced_name, referenced_link_name, referenced_type
from dba_dependencies
where OWNER = 'OWNER_NAME';
My required output is as follows:
Owner_Name
Procedure_Name
Referenced_name
Referenced_link
Referenced_type
Column_Name,
dml_type(select/insert/update).
Please help if possible..
columns will be in DBA_TAB_COLUMNS.
as for the SQL statements, this is a bit more difficult, but doable if you have Diagnostics pack licensed; here's the outline (works in 11g or above):
DBA_HIST_ACTIVE_SESS_HISTORY.top_level_sql_id is the SQL id of the calling procedure,
so listing DBA_HIST_ACTIVE_SESS_HISTORY.sql_id for that top_level_sql_id is "all" the SQL from the execution of the procedure.
DBA_HIST_SQL_TEXT can be queried to get the sql text for the sql_id.
If you don't have the Diagnostics Pack, you'd have to instrument v$session for the top_level_sql_id's and sql_id's and the look in v$sql for the text.

Any tools to export the whole Oracle DB as SQL scripts

Here is my problem, I wants to create a baseline on our development Dateabase (Oracle 10g), and check into our svn for version control, and after this we will use liquibase to help us manage the incremental database changes.
My problem is how should I create baseline of Oracle 10g? the database now consists of 500+ tables, with large amount of configuration data, and I wants my db baseline to base on a set SQL scripts to check into subversion, rather then check in Oracle dump..
I have try use liquibase generateChangeLog, but it have some performance problem.. can anyone can recommends me any tools that will help me
1. Scan any Oracle Schema
2. Generate a set of SQL Scripts (With Table structures, and Data)..
Thanks in advance
James!
Something like
SELECT DBMS_METADATA.GET_DDL('TABLE',table_name) FROM USER_TABLES;
is a good start. You can tweak it with PL/SQL and UTL_FILE to get it to write each table to a different file. You will probably need to do sequences too (though versioning them is fairly pointless), and maybe triggers/procedures/functions/packages etc.
Don't forget grants.
Have you tried Oracle's free SQLDeveloper tool? It gives you the possibility of exporting DDL and data.
EXPDP with CONTENT=METADATA_ONLY option, then IMPDP with SQLFILE=your_script.sql ?
Nicolas.
More general solution would be to dump DDL sql for selected list of tables, but additionally also other types of objects. This could be done by using all_objects and all_users views.
Example that worked for me:
select dbms_metadata.GET_DDL(u.object_type,u.object_name, u.owner)
from all_objects u
where 1=1
-- filter only selected object types
and u.object_type in ('TABLE', 'INDEX', 'FUNCTION', 'PROCEDURE', 'VIEW',
'TYPE', 'TRIGGER', 'SEQUENCE')
-- don't want system objects, generated, temp, invalid etc.
and u.object_name not like 'SYS_%'
and temporary!='Y'
and generated!='Y'
and status!='INVALID'
and u.object_name not like 'TMP_%'
and u.object_name not like '%$%'
-- if you want to filter only changed from some date/timestamp:
-- and u.last_ddl_time > '2014-04-02'
-- filter by owner
and owner in (
select username from dba_USERS where DEFAULT_TABLESPACE not like 'SYS%'
and username not in ('ORACLE_OCM')
and username not like '%$%'
)
;
I wrote a python script that refreshes db schema in incremental mode based on similar sql:
runs sql with last_ddl_time>=max(last_ddl_time from last refresh)
at the end stores last_ddl_time somewhere in filesystem for next refresh
References:
oracle dbms_metadata.GET_DDL function
oracle all_objects view

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