How to identify all stored procedures refering a particular table in Oracle - oracle

I am working with Oracle 12c and need to find all references where a specific table or view is being used in Stored Procedure/Function and packages.
I have found a this answer about MS SQL Server, but it's not related to Oracle, besides sp_help and sp_depends sometimes return inaccurate results.
I know to search in column text of table all_source, for example, this code (search only standard user defined package names, not system package):
SELECT type, name, line, text
FROM all_source
WHERE type = 'PACKAGE BODY'
AND name like 'P%'
AND UPPER(text) like '%' || p_table_or_view_name || '%'
ORDER BY name, line;
but I'm looking if there's a more elegant and/or standard solution in Oracle.
I'm also checking if this answer can help me in any way.
I will appreciate any assistance.

Use the ALL_DEPENDENCIES dictionary table:
SELECT *
FROM ALL_DEPENDENCIES
WHERE referenced_name = 'YOUR_TABLE_NAME'
AND owner = 'YOUR_USER';

Related

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.

How to find the columns used in a stored procedure

Is it possible to get a list of used columns in a particular procedure using PL/SQL? I have to check over 500 procedures in my Oracle DB and print out all the columns used in them.
Surprisingly, Oracle does make the calculated table dependencies in PL/SQL available for viewing:
select * from user_dependencies -- can also use all_ or dba_dependencies
where type = 'PROCEDURE' and REFERENCED_TYPE = 'TABLE';
But if you really need column-level dependencies, I think it'll be much more difficult. Here's a very simple answer that'll illustrate some of the problems with the question.
select name, type, line, text, table_name, column_name
from user_source
join user_tab_cols
on text like '%'|| column_name || '%';
So you can search through all your procedures for any strings that match an existing column name. I can think of dozens of problems with this approach; the commenters above mentioned some of them, like how deep into the call stack you want to look. Or depending on how your columns are named, ambiguous names (SID, MODIFIED_DATE, etc) will produce duplicate entries. And there's no way to distinguish between actual references to column names and local variables which happen to have the same spelling. Or comments. And views or synonyms can screw up your searching. It seems like a really tough question. I hope the tables from user_dependencies will be enough for your needs.

Is it possible to get the stored procedure name by having line number in PL\SQL?

I'm just writing a tool to automate a process. Out of it, I just want it to do fetch the stored procedure name if I give the line number of a package of many procs.
Is it possible to do so, or is there some other way to get the procedure name with line number or "specific text"?
Have a look at all_procedures
Maybe you can figure it out by using the column subprogram_id.
It seems like, this column identifies the procedures as they are defined in the package header.
Try to select from the SYS view ALL_SOURCE querying by the owner, package name and line number or owner package name and text.
Below are two examples that assume that you will replace MYOWNER,MYPACKAGE, Myprocedure and MYLINENUMBER with your own information.
select * from ALL_SOURCE
where OWNER = 'MYOWNER' and
TYPE='PACKAGE' and
NAME='MYPACKAGE' and
TEXT like 'PROCEDURE Myprocedure%'
select * from ALL_SOURCE
where OWNER = 'MYOWNER' and
TYPE='PACKAGE' and
NAME='MYPACKAGE' and
LINE = MYLINENUMBER

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%';

How to check if a stored procedure exist?

I have searched the net and I've found a post that uses the following snippet to check if a stored procedure exists:
select *
from USER_SOURCE
where type='PROCEDURE'
and name='my_stored_procedure.'
Is there any other way to check if a procedure exists?
Edited to add:
Before posting SQL Server ways, please I'm looking for ORACLE ways.
Alternatives:
USER_PROCEDURES:
SELECT *
FROM USER_PROCEDURES
WHERE object_name = 'MY_STORED_PROCEDURE'
USER_OBJECTS:
SELECT *
FROM USER_OBJECTS
WHERE object_type = 'PROCEDURE'
AND object_name = 'MY_STORED_PROCEDURE'
Something that worked for me!
SELECT text
FROM all_source
WHERE name = 'MY_SP_NAME'
ORDER BY line;
Alternatively you can try calling SP like this:
CALL MY_SP_NAME();
You might end up error like this, but that confirms you have SP defined there:
OCI Statement Execution failure.ORA-06553: PLS-306: wrong number or types of arguments in call to 'MY_SP_NAME'
The only way to see if a procedure exists in the database is though querying DBA_OBJECTS. The disadvantage here is that only a dba has access to this view. Second best is using all_objects. ALL_OBJECTS shows you the objects for which you have somehow a privilege. USER_OBJECTS only shows you your own objects.
Execute the query below in SQL*PLUS, ODBC Test,...
SELECT text FROM all_source WHERE name='MY_PROCEDURE' ORDER BY line
where MY_PROCEDURE is the stored procedure name.
Below is sample output:
Get Data All:
"TEXT"
"PROCEDURE Usp_Get_Blob
"(
"P_DOC_ID INT,
"P_DOC_TEXT OUT BLOB)
"as
"begin
" select B1
into p_doc_text
" from blobtest
" where ID = p_doc_id;
"end; "
I was not able to find stored procedure with any of the methods above.
Reason: stored procedure was inside package. Oracle uses packages to gather several stored procedures in one module.
This will display the stored procedure and its contents stored in the table.
select
name c1,
text c2
from
dba_source
where
name = upper('procedure_name')
order by
line asc;
select *
from USER_SOURCE
where type='PROCEDURE'
and name='my_stored_procedure.'

Resources