How can I get all the objects connected to a table - oracle

I have to drop a table and to create a view with the same fields and name.
How can I get previously all the objects (tables, triggers, procedure, ...) connected to the original table so as to eventually or recompiling either modifying them?
Oracle version 11g
Thanks!

Run such a query; currently, I'm connected as a privileged user who is capable of querying DBA_DEPENDENCIES.
SQL> SELECT owner, name, type
2 FROM dba_dependencies
3 WHERE 1 = 1
4 AND referenced_owner = 'SCOTT'
5 AND referenced_type = 'TABLE'
6 AND referenced_name = 'EMP';
OWNER NAME TYPE
------------------------------ ------------------------------ ------------------
SCOTT TRG_BIU_EMP TRIGGER
MIKE PKG_EMPLOYEE PACKAGE BODY
SQL>
It says that emp table, owned by scott, is referenced by two other objects:
trigger named trg_biu_emp owned by scott
package body named pkg_employee owned by mike
You can also go with all_dependencies and user_dependencies (pay attention to their description! owner column is missing in user_ views), but you'll get fewer and fewer results because both of them contain less information than dba_dependencies.
Therefore, if you don't want to miss something, look everywhere (i.e. dba_ views). If you don't have required privileges, talk to your DBA.
Also, note that such a query won't discover possible references to that object elsewhere, such as front-end applications developed in e.g. Oracle Forms and Reports or Apex or ...

Related

Is it possible to add a custom metadata field to Oracle Data Dictionary?

Is it possible to add a metadata field at column-level (in the Oracle Data Dictionary)?
The purpose would be to hold a flag identifying where individual data items in a table have been anonymised.
I'm an analyst (not a DBA) and I'm using Oracle SQL Developer which surfaces (and enables querying of) the COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_DEFAULT, COLUMN_ID, and COMMENTS metadata fields of our Oracle DB (see pic).
I'd be looking to add another metadata field at this level (essentially, to add a second 'COMMENTS' field) to hold the 'Anonymisation' flag, to support easy querying of our flagged-anonymised data.
If it's possible (and advisable / supportable), I'd be grateful for any advice for describing the steps required to enable this, which I can then discuss with our Developer and DBA.
Short answer: NO.
But where could you keep that information?
In your data model.
Oracle provides a free data modeling solution, Oracle SQL Developer Data Modeler. It provides the ability to mark table/view columns as sensitive or PII.
Those same models can be stored back in your database so they can be accessed via SQL.
Once you've marked up all of your sensitive attributes/columns, and store it back into the database, you can query it back out.
Disclaimer: I work for Oracle, I'm the product manager for Data Modeler.
[TL;DR] Don't do it. Find another way.
If it's advisable
NO
Never modify the data dictionary; (unless Oracle support tells you to) you are likely to invalidate your support contract with Oracle and may break the database and make it unusable.
If it's possible
Don't do this.
If you really want to try it then still don't.
If you really, really want to try it then find a database you don't care about (the don't care about bit is important!) and log on as a SYSDBA user and:
ALTER TABLE whichever_data_dictionary_table ADD anonymisation_flag VARCHAR2(10);
Then you can test whether the database breaks (and it may not break immediately but at some point later), but if it does then you almost certainly will not get any support from Oracle in fixing it.
Did we say, "Don't do it"... we mean it.
As you already know, you shouldn't do that.
But, nothing prevents you from creating your own table which will contain such an info.
For example:
SQL> CREATE TABLE my_comments
2 (
3 table_name VARCHAR2 (30),
4 column_name VARCHAR2 (30),
5 anonymisation VARCHAR2 (10)
6 );
Table created.
Populate it with some data:
SQL> insert into my_comments (table_name, column_name)
2 select table_name, column_name
3 from user_tab_columns
4 where table_name = 'DEPT';
3 rows created.
Set the anonymisation flag:
SQL> update my_comments set anonymisation = 'F' where column_name = 'DEPTNO';
1 row updated.
When you want to get such an info (along with some more data from user_tab_columns, use (outer) join:
SQL> select u.table_name, u.column_name, u.data_type, u.nullable, m.anonymisation
2 from user_tab_columns u left join my_comments m on m.table_name = u.table_name
3 and m.column_name = u.column_name
4 where u.column_name = 'DEPTNO';
TABLE_NAME COLUMN_NAME DATA_TYPE N ANONYMISATION
---------- --------------- ------------ - ---------------
DEPT DEPTNO NUMBER N F
DSV DEPTNO NUMBER N
DSMV DEPTNO NUMBER Y
EMP DEPTNO NUMBER Y
SQL>
Advantages: you won't break the database & you'll have your additional info.
Drawbacks: you'll have to maintain the table manually.

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.

What's the difference between v$pdbs and dba_pdbs in Oracle?

I'm new to pluggable databases and am puzzled by the dictionary views DBA_PDBS and V$PDBS. What's the differnence? The documentation is not helpful, either:
V$PDBS displays information about PDBs associated with the current instance.
1
SELECT * FROM v$pdbs;
CON_ID NAME OPEN_MODE ...
2 PDB$SEED READ ONLY
3 XEPDB1 READ WRITE
DBA_PDBS describes PDBs belonging to a given CDB.
2
SELECT * FROM dba_pdbs;
PDB_ID PDB_NAME STATUS ...
2 PDB_SEED NORMAL
3 XEPDB1 NORMAL
Internally, V$PDBS seems to be based on SYS.X$CON, while DBA_PDBS is based on SYS.CONTAINERS$.
There are similar cases with V$DATAFILE vs DBA_DATA_FILES or V$TABLESPACE vs DBA_TABLESPACES: in this case these views data are read from database control files and are likely redundant for restore/recovery purposes (ie when the SYSTEM tablespace is not yet available, DBAxxx views are not there but when database instance needs to work on datafiles and tablespaces). It's likely for the same reason that we have V$PDBS in addition to DBA_PDBS.

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.

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