oracle in the real world - oracle

I've recently started using oracle after a few years of using mysql. I was immediately struck by how verbose oracle is compared to mysql. Four-word queries (like SHOW INDEX IN < table> ) become four-line queries in oracle.
My question is: how do real oracle DBAs interact with oracle efficiently. There must be some way to alias commonly used commands (like you do in the unix shell). I find it hard to believe that they would type something like
select index_name, column_name, column_position from user_ind_columns
where table_name='MYTABLENAME' order by index_name, column_position
every time they wanted to do something as simple as list the indexes of a table. Otherwise how can they get any work done?

You can use an IDE like SQL Developer or Toad; these have a UI to browse tables, indexes and other objects without typing any commands.
Or in SQL Plus you can simply save commonly used queries as scripts in files, for example a script called show_index could contain:
select index_name, column_name, column_position from user_ind_columns
where table_name=upper('&TABLENAME.') order by index_name, column_position;
You would run this in SQL Plus like this:
SQL> #show_index
Enter value for tablename: mytable

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.

SELECT statement in SQL DEVELOPER

So I am new in SQL DEVELOPER tools and I have written a simple select statement like:
SELECT * FROM employee;
it worked fine but there was a yellow warning mark underneath SELECT and I clicked on that and my query changes into the following query:
SELECT "A1"."EMPLOYEE_ID" "EMPLOYEE_ID","A1"."FIRST_NAME" "FIRST_NAME","A1"."LAST_NAME" "LAST_NAME","A1"."SALARY" "SALARY", "A1"."DEPARTMENT_ID" "DEPARTMENT_ID","A1"."MANAGER_ID" "MANAGER_ID","A1"."HIRE_DATE" "HIRE_DATE"
FROM "INTRO_USER"."EMPLOYEE" "A1";
My Quest is what is the difference between these two queries? although their output is the same
The glob * has been expanded to all column of the table. The table name EMPLOYEE is aliased to A1 to make it shorter.
The feature you are seeing is called 'SQL Text Expansion,' and it's setup to allow you to see what your query would look like if you were working with one or more VIEWS.
For example, SELECT * FROM ALL_TABLES is quite complicated. This feature allows you to see what's actually involved when running that SQL.
https://www.thatjeffsmith.com/archive/2014/12/sql-developer-and-a-12c-magic-trick/
There is probably no change or expected delta in the performance or execution plan of the 2 versions of your query.

how to get select statement query which was used to create table in oracle

I created a table in oracle like
CREATE TABLE suppliers AS (SELECT * FROM companies WHERE id > 1000);
I would like to know the complete select statement which was used to create this table.
I have already tried get_ddl but it is not giving the select statement. Can you please let me know how to get the select statement?
If you're lucky one of these statements will show the DDL used to generate the table:
select *
from gv$sql
where lower(sql_fulltext) like '%create table suppliers%';
select *
from dba_hist_sqltext
where lower(sql_text) like '%create table%';
I used the word lucky because GV$SQL will usually only have results for a few hours or days, until the data is purged from the shared pool. DBA_HIST_SQLTEXT will only help if you have AWR enabled, the statement was run in the last X days that AWR is configured to hold data (the default is 8), the statement was run after the last snapshot collection (by default it happens every hour), and the statement ran long enough for AWR to think it's worth saving.
And for each table Oracle does not always store the full SQL. For security reasons, DDL statements are often truncated in the data dictionary. Don't be surprised if the text suddenly cuts off after the first N characters.
And depending on how the SQL is called the case and space may be different. Use lower and lots of wildcards to increase the chance of finding the statement.
TRY THIS:
select distinct table_name
from
all_tab_columns where column_name in
(
select column_name from
all_tab_columns
where table_name ='SUPPLIERS'
)
you can find table which created from table

What does Oracle use "select 1 from sys.obj$ where 1=0" for?

I was in our Oracle DB and saw this in the messages.
select 1 from sys.obj$ where 1=0;
I'm curious as to what it does. Is it just a session being initiated, a check to see if there is a sign of life?
That query is automatically generated by Oracle SQL Developer, it's nothing nefarious.
I can't tell exactly what the query is used for. But when I looked for it on a few hundred of our databases I found about 20 rows for completely unrelated users and databases. The only thing they had in common was the MODULE was set to "SQL Developer".
select executions, parsing_schema_name, module, first_load_time
from gv$sql
where sql_text = 'select 1 from sys.obj$ where 1=0';
Further queries on GV$SQL and DBA_AUDIT_TRAIL show other boring data dictionary queries being run at the same time. Which leads me to believe it's one of a set of background queries run for some Oracle SQL Developer feature.
select executions, parsing_schema_name, first_load_time, gv$sql.*
from gv$sql
where parsing_schema_name = '<user from above>'
order by gv$sql.first_load_time desc;

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

Resources