Oracle SQL Developer window view with table dependencies - sql

In Oracle SQL developer GUI, I opened a table and a window with attributes appear. Here is a window tab named Dependencies.
I found this query:
select OWNER
, name
, type
, referenced_name
, referenced_type
from all_dependencies;
But didn't show output for all owners like as Oracle SQL Developer.
How can I obtain these results via a query SQL with all owners?
Thanks!

With a query like:
select owner, name, type, referenced_owner, referenced_name, referenced_type
from dba_dependencies
where referenced_owner = user and referenced_name = 'YOUR_TABLE_NAME';
or using bind variables:
var object_owner varchar2(30);
var object_name varchar2(30);
exec :object_owner := user;
exec :object_name := 'YOUR_TABLE_NAME';
select owner, name, type, referenced_owner, referenced_name, referenced_type
from dba_dependencies
where referenced_owner = :object_owner and referenced_name = :object_name ;
You can actually see the queries that SQL Developer runs under the hood. If you go to to the View menu and choose Log, or hit CtrlShiftL (assuming you're using Windows) you'll get a docked window which by default is titled "Messages - Log". At the bottom of that are two tabs, with "Messages" selected. If you click "Statements" instead you can see the statement and bind variables used.
In this case there are three statements issued when you refresh the dependencies tab, two of which are variations on what I've shown above - they get a few more columns, and check dependencies going both ways:
select owner, name, type, referenced_owner, referenced_name, referenced_type ,
owner sdev_link_owner, name sdev_link_name, type sdev_link_type
from Dba_DEPENDENCIES
where referenced_owner = :OBJECT_OWNER and referenced_name = :OBJECT_NAME
select owner, name, type, referenced_owner, referenced_name, referenced_type ,
referenced_owner sdev_link_owner, referenced_name sdev_link_name, referenced_type sdev_link_type
from Dba_DEPENDENCIES
where owner = :OBJECT_OWNER and name = :OBJECT_NAME
They are a good place to start if you want to figure out how replicate what you can see.
If you are connected as a user that doesn't have the privileges necessary to see the dba_dependencies table, SQL Developer instead falls back to all_dependencies:
select owner, name, type, referenced_owner, referenced_name, referenced_type ,
owner sdev_link_owner, name sdev_link_name, type sdev_link_type
from ALL_DEPENDENCIES
where referenced_owner = :OBJECT_OWNER and referenced_name = :OBJECT_NAME
select owner, name, type, referenced_owner, referenced_name, referenced_type ,
referenced_owner sdev_link_owner, referenced_name sdev_link_name, referenced_type sdev_link_type
from Dba_DEPENDENCIES
where owner = :OBJECT_OWNER and name = :OBJECT_NAME
which will only show information about objects you have select/execute privileges against. In the first query I showed above you can just change dba_dependencies to all_dependencies to see the equivalent (visible) results.
If you run the SQL manually as the same user you're connected to SQL Developer as, you'll see the same results.

Related

How we can know what views are existed in particular table

In Oracle there is table named customers. If we want to know what views depend on the customer table how can we find that out?
You could query the sys.all_dependancies object.
This will output the referencing object which is the name of the view using the table specified
SELECT referenced_owner || '.' || referenced_name as table_name,
referenced_type as type,
owner || '.' || name as referencing_object,
type as referencing_type
FROM sys.all_dependencies
WHERE referenced_type = 'VIEW'
AND referenced_name = 'customers' -- put your table/view name here

How to find the tables affected in a PL SQL package?

I have to find out the list of tables into which insertion or updation happens in my existing PL SQL package. I started analyzing the package. The concern is the package code runs in thousands of lines of code and in turn
calls many other packages. Also, the code was not written by me. I cannot run AWR report since it is Development environment.
Is there a way to get the tables into which insertion/updation happens after initiating the transaction?
Could a trigger be written to suit my requirement?
-- plain
select *
from dba_dependencies
where name = 'PACKAGE_NAME' and owner = 'PACKAGE_OWNER'
and type in ('PACKAGE', 'PACKAGE BODY') and referenced_type = 'TABLE';
-- hierarchy
select distinct referenced_owner, referenced_name, referenced_type, referenced_link_name
from dba_dependencies
where referenced_type = 'TABLE'
start with name = 'PACKAGE_NAME' and owner = 'PACKAGE_OWNER'
and type in ('PACKAGE', 'PACKAGE BODY')
connect by nocycle prior referenced_name = name and prior referenced_owner = owner
and replace(prior referenced_type, 'PACKAGE BODY', 'PACKAGE') = replace(type, 'PACKAGE BODY', 'PACKAGE')
and referenced_owner not in ('SYS', 'SYSTEM', 'OUTLN' , 'AUDSYS')
order by 1, 2, 3;
#akk0rd87 has the better answer -- DBA_DEPENDENCIES, with a CONNECT BY to get table usages by called procedures.
The only thing his answer wouldn't find is tables used directly because of dynamic SQLs (e.g., EXECUTE IMMEDIATE). For that, you can use fine-grained auditing.
To me, this approach is just a backup after you follow #akk0rd87's advice.
Since SO in not a free code writing service, I'll just give you the broad strokes.
1) Create a table to serve as your audit trail. Make sure it has the following columns, at least:
SCHEMA_NAME (30 chars)
TABLE_NAME (30 chars)
CALL_STACK (4000 chars)
SQL_STMT (4000 chars)
2) Create a package to serve as an audit handler. I will give you code for this, because it must follow the exact API I give to be usable with fine grained auditing.
CREATE OR REPLACE PACKAGE BODY xxcust_table_access_aud_pkg AS
PROCEDURE audit_access ( schema_name VARCHAR2, table_Name VARCHAR2, policy_name VARCHAR2 ) IS
BEGIN
INSERT INTO your_audit_table ( SCHEMA_NAME, TABLE_NAME, CALL_STACK, SQL_STMT )
VALUES ( schema_name,
table_Name,
substr(DBMS_UTILITY.format_call_stack,1,4000),
substr(SYS_CONTEXT ('userenv', 'CURRENT_SQL'),1,4000)
)
EXCEPTION
WHEN others THEN
null;
END;
END xxcust_table_access_aud_pkg ;
3) Loop through all the tables in your application schema and call DBMS_FGA.ADD_POLICY for each one. E.g.,
FOR r IN ( ... all my tables ... ) LOOP
DBMS_FGA.add_policy(object_schema=> r.owner,
object_name => r.table_name,
policy_Name => -- make up something unique, maybe table_name plus some number,
audit_condition => '1=1',
audit_column => null,
handler_schema => -- your schema,
handler_module => 'XXCUST_TABLE_ACCESS_AUD_PKG', -- the package above
enable => true);
4) Run your package and check the table for results
5) Repeat step 3, but drop the policies instead of adding them.
Not sure if a Trigger can be a solution, Below can be one of the solutions, with some manual effort though:
DO a grep on the main package to find the other package names, note the names of all packages including the main one.
Get the source code of all these packages from " all_source" table, with where clause on "NAME" attribute and specifying the package names identified above.
Spool the source for above packages in a text file and do a grep on insert and update commands.

How to select all the stored procedures from Oracle database with one statement?

I want to view all the stored procedure implementations owned by fooUser in an Oracle database.
By using rownum, I am able to do this for the first procedure in dba_objects table, but there are many procedures in dba_objects table owned by fooUser.
I do not want to write a stored procedure to achieve this, I want to do this with one SQL statement.
Query to get the first stored procedure implementation:
SELECT
line, text
FROM
dba_source
WHERE
name = (SELECT object_name
FROM dba_objects
WHERE object_type = 'PROCEDURE'
AND owner = 'fooUser' AND rownum = 1)
AND type = 'PROCEDURE'
ORDER BY
line
to get source of procedure you can use dbms_metadata.get_ddl
see documentation here dbms_metadata
for example script below returns you list of procedures and source for each procedure where owner is usr1
select object_name
, dbms_metadata.get_ddl(object_type,object_name) from dba_procedures
where owner = 'USR1'
and object_type = 'PROCEDURE'
OR
if you need just line-by-line text for all procedures
SELECT line, text
FROM dba_source
WHERE owner = 'SCM'
AND type = 'PROCEDURE'
ORDER BY name, line
try this:
SELECT line, text
FROM dba_source
WHERE owner = ?
AND name = ?
AND type = 'PROCEDURE'
ORDER BY line
update #1:
SELECT line, text
FROM dba_source
WHERE owner = 'foouser'
AND type = 'PROCEDURE'
ORDER BY line
update #2:
SELECT line, text, name
FROM dba_source
WHERE owner = 'foouser'
AND type = 'PROCEDURE'
ORDER BY name, line

Find all views that contain a certain table or column

In a legacy database infrastructure, how do I best find views that access a certain table or column? I'm currently refactoring certain tables (i.e. delete unused columns) and I want to find all views that still rely on those columns and will break, if I remove the columns.
Is there any tool/feature to search through all view definitions in Oracle SQL Developer?
You can use something like function dependent_views, code below. Example usage:
select dependent_views('CUSTOMER_NAME', 'CUSTOMERS') list from dual
Output:
LIST
-----------------
SCOTT.V_PERSONS
Function searches dependendent views in ALL_DEPENDENCIES, next searches TEXT column from ALL_VIEWS for occurence of column_name.
Note: Because all_dependences may not contain full data of dependent objects (for instance when view was created by execute immediate) - my function may not find this object.
Also if column_name is substring of other column - function may return to many views.
create or replace function dependent_views
(i_column varchar2, i_table varchar2, i_owner varchar2 default USER)
return varchar2 is
o_ret varchar2(4000) := '';
v_text long := '';
begin
for o in (
select * from all_dependencies
where referenced_name = upper(i_table)
and referenced_owner = upper(i_owner)
and type = 'VIEW')
loop
begin
select text into v_text from all_views
where view_name = o.name and owner = o.owner;
exception when no_data_found then
null;
end;
if upper(v_text) like '%'||upper(i_column)||'%' then
o_ret := o_ret||o.owner||'.'||o.name||' ';
end if;
end loop;
return o_ret;
end dependent_views;
how do I best find views that access a certain table
You could query the [USER|ALL|DBA]_DEPENDENCIES view.
SELECT name ,
type ,
referenced_name ,
referenced_type
FROM user_dependencies
WHERE TYPE = 'VIEW'
AND NAME = '<VIEW_NAME>'
AND referenced_type = '<TABLE_NAME'>;
To get the result for all the views at once, remove the filter NAME = '<VIEW_NAME>'.
For example,
SQL> column name format a15
SQL> column type format a15
SQL> column referenced_name format a15
SQL> column referenced_type format a15
SQL> SELECT name ,
2 type ,
3 referenced_name ,
4 referenced_type
5 FROM user_dependencies
6 WHERE TYPE = 'VIEW';
NAME TYPE REFERENCED_NAME REFERENCED_TYPE
--------------- --------------- --------------- ---------------
EMP_CUSTOM_VIEW VIEW EMP TABLE
EMP_VIEW VIEW EMP TABLE
SQL>
Cause you search for all views that access certain table, this might help:
select
name,
type,
referenced_name,
referenced_type
from user_dependencies
where type = 'VIEW'
and referenced_type = 'TABLE'

Query to display all tables and views

I've come up with a query that displays all tables and views of a specific owner. What I would like to do now, but am having an issue with, is that I would like to have a second column which line by line will indicate whether the field is a "table" or "view". Is this possible? if so, how might I go about this?
select table_name
from all_tables
where owner = '<owner>'
UNION
select view_name
from all_views
where owner = '<owner>'
order by table_name;
I'd prefer the xxx_objects views myself for this purpose (as Justin says), but if you specifically need other data from the table and view views, you can add extra info thus:
select 'Table' AS object_type, table_name
from all_tables
where owner = '<owner>'
UNION ALL
select 'View' AS object_type, view_name
from all_views
where owner = '<owner>'
order by table_name;
Note I've changed it to use UNION ALL because there will be no collisions between the two result sets.
I'd use all_objects instead
select object_name, object_type
from all_objects
where object_type in ('TABLE', 'VIEW')
and owner = <<schema name>>
order by object_name