Friday 25 April 2008

Invoking and Executing a Script from OEM

When including script names in OEM you must carefully include the fully-qualified path for the script: (i.e. /u01/app/oracle/scripts/myscript.sql). Placing custom scripts within OEM is a great way to improve reporting. Here is a quick overview of script execution from OEM:

  1. Create a "new event" from the OEM console
  2. Choose "enable unsolicited event" and then "test unsolicited event"
  3. Enter the script name with the full path.
You can also use the oemevent command to invoke a SQL script from OEM:

root> oemevent /u01/app/oracle/scripts/myscript.sql destination alert "Monitored destination message"

Thursday 24 April 2008

Database Link From Oracle to SQL Server

After you succeed connecting Oracle with SQL Server probably you want to create database link between it. Oracle heterogeneous services allow you to define a database link between Oracle and SQL Server, as well as links to DB2 and other inferior databases.

Here are complete notes in creating a database link between Oracle and SQL Server.

1. Install Oracle ODBC drivers on the server (your local Oracle database) that will access the remote SQL Server database using the database link.
2. Setup the ODBC connection on the local Oracle database using the Windows ODBC Data Source Administrator
3. Test the ODBC drivers to ensure that connectivity is made to the SQL Server database.
4. Ensure that your global_names parameter is set to False.
5. Configure the Oracle Heterogeneous services by creating an initodbc.ora file within the Oracle database.

6. Modify the Listener.ora file.


SID_NAME is the DSN for the remote database.
ORACLE_HOME is the actual Oracle home file path.
PROGRAM tells Oracle to use heterogeneous services.

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME=Cas30C) -- Enter the DSN on this line
(ORACLE_HOME = c:\oracle10gdb) -- Enter your Oracle home on this line
(PROGRAM = hsodbc) ) )



7. Modify the Tnsnames.ora file. This is the Oracle database installation accessed by the users to connect to the ODBC drivers

(DESCRIPTION=
(ADDRESS_LIST=
(Address=(PROTOCOL=TCP)
(HOST=
-- (Server x)
(PORT=1521))) -- Enter the port on which the server x Oracle installation
-- is listening
(CONNECT_DATA=(SID=Cas30c)) - Enter the DSN name
(HS=OK) -- Enter this value. It tells Oracle to use hetergeneous services
)


8. Reload the listener on local Oracle database
9. Create a database link on the local Oracle installation that accesses the heterogeneous connection, which, in turn, connect to SQL Server.
10. Run a SQL Server Select statement from the Oracle installation using the database link.

Accessing Oracle Alert Log via SQL with External Tables

Starting in Oracle9i you can map external flat files to Oracle tables.
Mapping the Oracle alert log is easy and once defined, all you have to do is query it with standard SQL syntax:

create directory BDUMP as '/u01/app/oracle/admin/mysid/bdump';

create table
alert_log ( msg varchar2(80) )
organization external (
type oracle_loader
default directory BDUMP
access parameters (
records delimited by newline
)
location('alrt_mysid.log')
)
reject limit 1000;


Now we can easily extract important Oracle alert log information without leaving SQL*Plus:
select msg from alert_log where msg like '%ORA-00600%';

ORA-00600: internal error code, arguments: [17034], [2940981512], [0], [], [], [ ], [], []
ORA-00600: internal error code, arguments: [18095], [0xC0000000210D8BF8], [], [], [], [], []
ORA-00600: internal error code, arguments: [4400], [48], [], [], []

Tuesday 22 April 2008

Computing date differences

One of the confounding problems with Oracle DATE datatypes is the computation of elapsed time.

Oracle supports date arithmetic and you can make expressions like "date1 - date2" to get the difference between the two dates. Once you have the date difference, you can use simple techniques to express the difference in days, hours, minutes or seconds.

To get the values for data differences, you must choose you unit of measurement, and this is done with the data format mask:

It might be tempting to use sophisticated conversion functions to convert a data, but we will see that this is not the most elegant solution:

round(to_number(end-date-start_date))– elapsed days



round(to_number(end-date-start_date)*24)– elapsed hours


round(to_number(end-date-start_date)*1440)– elapsed minutes

How are elapsed time data displayed by default? To find out, we issue a simple SQL*plus query:

SQL> select sysdate-(sysdate-3) from dual;



SYSDATE-(SYSDATE-3)

-------------------

3

Here we see that elapsed times are expressed in days. Hence, we can use easy conversion functions to convert this to hours or minutes:

However, when the minutes are not a whole number, we have the problem of trailing decimal places:
select

(sysdate-(sysdate-3.111))*1440

from

dual;


(SYSDATE-(SYSDATE-3.111))*1440

------------------------------

4479.83333

Of course, we can overcome this with the ROUND function, remembering that we must first convert the DATE datatype to a NUMBER:
select

round(to_number(sysdate-(sysdate-3.111))*1440)

from

dual;



ROUND(TO_NUMBER(SYSDATE-(SYSDATE-3.111))*1440)

----------------------------------------------

4480

Hence, we can use these functions to convert an elapsed time into rounded elapsed minutes, and place the value inside an Oracle table. In this example, we have a logoff system-level trigger that computes the elapsed session time and places it inside a Oracle STATSPACK user_log extension table:
update

perfstat.stats$user_log

set

elapsed_minutes =

round(to_number(logoff_time-logon_time)*1440)

where

user = user_id

and

elapsed_minutes is NULL;

Oracle SQL : Coding a matrix of display values

Oracle has a fascinating non-ANSI feature called an in-line view. The in-line view allows for a query to be placed into the FROM clause of an SQL statement, where you would normally place a table name.

By performing a SELECT in the FROM clause, we can summarize two columns, and display a third value based on two other columns.

In the example below, we take the employee name (ename) and the department number (deptno) and display the salary of the employee by their department.

prompt Display of Salary by Department



SELECT

*

FROM (SELECT

ename,

sum(decode(deptno,10,sal)) DEPT10,

sum(decode(deptno,20,sal)) DEPT20,

sum(decode(deptno,30,sal)) DEPT30,

sum(decode(deptno,40,sal)) DEPT40

FROM

emp

GROUP BY

ename)

ORDER BY 1;



Display of Salary by Department



ENAME DEPT10 DEPT20 DEPT30 DEPT40

---------- ---------- ---------- ---------- ----------

ADAMS 1100

ALLEN 1600

BLAKE 2850

CLARK 2450

FORD 3000

JAMES 950

JONES 2975

KING 5000

MARTIN 1250

MILLER 1300

SCOTT 3000

SMITH 800

TURNER 1500

WARD 1250


This type of query is very useful for Oracle data warehouse system where you must display information from a FACT table according to the values of two other columns.

Monday 17 March 2008

Oracle Package Initialization

Did you notice that Oracle PL/SQL packages can have an initialization section? The initialization part of a package is run only once, the first time you reference the package. Here is an example:

CREATE PACKAGE emp_actions AS
/* Declare externally callable subprograms. */
FUNCTION hire_employee (
ename VARCHAR2,
job VARCHAR2,
mgr REAL,
sal REAL,
comm REAL,
deptno REAL) RETURN INT;
END emp_actions;

CREATE PACKAGE BODY emp_actions AS
number_hired INT; -- visible only in this package

/* Fully define subprograms specified in package. */
FUNCTION hire_employee (
ename VARCHAR2,
job VARCHAR2,
mgr REAL,
sal REAL,
comm REAL,
deptno REAL) RETURN INT IS
new_empno INT;
BEGIN
SELECT empno_seq.NEXTVAL INTO new_empno
FROM dual;
INSERT INTO emp VALUES (new_empno, ename, job,
mgr, SYSDATE, sal, comm, deptno);
number_hired := number_hired + 1;
RETURN new_empno;
END hire_employee;

BEGIN -- initialization part starts here
INSERT INTO emp_audit
VALUES (SYSDATE, USER, 'EMP_ACTIONS');
number_hired := 0;
END emp_actions;


The initialization part of a package is run just once, the first time you reference the package. So, in the last example, only one row is inserted into the database table emp_audit. Likewise, the variable number_hired is initialized only once.

Every time the procedure hire_employee is called, the variable number_hired is updated. However, the count kept by number_hired is session specific. That is, the count reflects the number of new employees processed by one user, not the number processed by all users.

Monday 10 March 2008

Using rsync to Copy Oracle Home Directories

If you're using UNIX for your ORACLE database server, it is possible to copy the Oracle Database Software (the Oracle Home directory) from one server to another using rsync.

Here is the example rsync syntax to copy the Oracle Home from one server (svr1) to another server (svr2). This process will ensure that all symbolic links and files owned by root get copied over correctly. Login to the source database server (svr1) as the root user account and run the following:


[root@svr1 ~]# rsync -auvzpogl -e ssh /u01/app/oracle/product/10.2.0/db_1/ svr2:/u01/app/oracle/product/10.2.0/db_1/

Sending E-Mail in PL/SQL

Here some example code you can use for sending email from within PL/SQL

CREATE OR REPLACE PROCEDURE SEND_MAIL_TCP (
msg_from VARCHAR2 := 'sender@testing.com'
, msg_to VARCHAR
, msg_subject VARCHAR2 := 'E-Mail message from your database'
, msg_text VARCHAR2 := ''
)
IS
c UTL_TCP.CONNECTION;
rc INTEGER;
BEGIN
c := UTL_TCP.OPEN_CONNECTION('localhost', 25); -- open the SMTP port 25 on local machine
rc := UTL_TCP.WRITE_LINE(c, 'HELO localhost');
rc := UTL_TCP.WRITE_LINE(c, 'MAIL FROM: '||msg_from);
rc := UTL_TCP.WRITE_LINE(c, 'RCPT TO: '||msg_to);
rc := UTL_TCP.WRITE_LINE(c, 'DATA'); -- Start message body
rc := UTL_TCP.WRITE_LINE(c, 'Subject: '||msg_subject);
rc := UTL_TCP.WRITE_LINE(c, '');
rc := UTL_TCP.WRITE_LINE(c, msg_text);
rc := UTL_TCP.WRITE_LINE(c, '.'); -- End of message body
rc := UTL_TCP.WRITE_LINE(c, 'QUIT');
UTL_TCP.CLOSE_CONNECTION(c); -- Close the connection
EXCEPTION
WHEN others THEN
RAISE_APPLICATION_ERROR(-20000, 'Unable to send e-mail message from PL/SQL routine.');
END;

Tuesday 19 February 2008

Another Oracle apps DBA Interview Questions (with answer)

Questions:

  1. What happens if the ICM goes down?
  2. How will you speed up the patching process?
  3. How will you handle an error during patching?
  4. Provide a high-level overview of the cloning process and post-clone manual steps.
  5. Provide an introduction to AutoConfig. How does AutoConfig know which value from the XML file needs to be put in which file?
  6. Can you tell me a few tests you will do to troubleshoot self-service login problems? Which profile options and files will you check?
  7. What could be wrong if you are unable to view concurrent manager log and output files?
  8. How will you change the location of concurrent manager log and output files?
  9. If the user is experiencing performance issues, how will you go about finding the cause?
  10. How will you change the apps password?
  11. Provide the location of the DBC file and explain its significance and how applications know the name of the DBC file.
Answers:
  1. All the other managers will keep working. ICM only takes care of the queue control requests, which means starting up and shutting down other concurrent managers.

    • You can merge multiple patches.
    • You can create a response file for non-interactive patching.
    • You can apply patches with options (nocompiledb, nomaintainmrc, nocompilejsp) and run these once after applying all the patches.
  2. Look at the log of the failed worker, identify and rectify the error and restart the worker using adctrl utility.
  3. Run pre-clone on the source (all tiers), duplicate the DB using RMAN (or restore the DB from a hot or cold backup), copy the file systems and then run post-clone on the target (all tiers).
    Manual steps (there can be many more):
    • Change all non-site profile option values (RapidClone only changes site-level profile options).
    • Modify workflow and concurrent manager tables.
    • Change printers.
  4. AutoConfig uses a context file to maintain key configuration files. A context file is an XML file in the $APPL_TOP/admin directory and is the centralized repository.
    When you run AutoConfig it reads the XML files and creates all the AutoConfig managed configuration files.
    For each configuration file maintained by AutoConfig, there exists a template file which determines which values to pick from the XML file.

    • Check guest user/password in the DBC file, profile option guest user/password, the DB.
    • Check whether apache/jserv is up.
    • Run IsItWorking, FND_WEB.PING, aoljtest, etc.
  5. Most likely the FNDFS listener is down. Look at the value of OUTFILE_NODE_NAME and LOGFILE_NODE_NAME in the FND_CONCURRENT_REQUESTS table. Look at the FND_NODES table. Look at the FNDFS_ entry in tnsnames.ora.
  6. The location of log files is determined by parameter $APPLCSF/$APPLLOG and that of output files by $APPLCSF/$APPLOUT.

    • Trace his session (with waits) and use tkprof to analyze the trace file.
    • Take a statspack report and analyze it.
    • O/s monitoring using top/iostat/sar/vmstat.
    • Check for any network bottleneck by using basic tests like ping results.

    • Use FNDCPASS to change APPS password.
    • Manually modify wdbsvr.app/cgiCMD.dat files.
    • Change any DB links pointing from other instances.

    • Location: $FND_TOP/secure directory.
    • Significance: Points to the DB server amongst other things.
    • The application knows the name of the DBC file by using profile option "Applications Database Id."

Five DBA Best Practices

Multiple Oracle Homes
My favorite best practice is the one about multiple Oracle Homes. Here it how it goes. When applying a patch or a patchset, I recommend against applying to the existing Oracle Home. Instead, I suggest creating a new Oracle Home, and apply the patches there.

I create the first Oracle Home at /app/oracle/db_1, for instance. When a patch comes out, I install the whole Oracle software in a different home -- /app/oracle/db_2 -- and then apply the patch there. During the process of installation and patch application, the database is up and running, as it runs off the home /db_1. When the outage window comes, all I have to do is to shut down Oracle; change Oracle Home to db_2 and bring the database up. If there is a problem, I can reset the Oracle Home back to the old one.

So, here is the conventional approach:

1. Shut down the database
2. Apply patch to the Oracle Home
3. Start the database
4. In case of problems:
5. Shut down the database
6. Roll back the patch
7. Start the database

Steps 2 and 6 could take as much as three hours depending on the amount of patching. The database is down during these times.

In the new approach:

1. Install new Oracle Home
2. Apply the patch to the new Home
3. Shut down the database
4. Change Oracle Home to the new location
5. Start the database
6. In case of problems:
7. Shut down the database
8. Change Oracle Home to the old one
9. Start the database

The database is down only during steps 4 and 8, which takes a couple of minutes at the most, not hours.

So, here are the advantages:

  1. The downtime is significantly reduced, to one 60th of the original time.
  2. The risk is reduced significantly, as there is no rolling back a patch; you just go to the older version.
  3. You can perform a "diff" on these two homes to see what changed. You can see the differences across multiple homes as well.
  4. You can take several databases running on the same server to the new Oracle Home one by one.
  5. You can see the various Oracle Homes and what patch level they are on using the inventory.

The only negative part is the space consumption -- you need space for two Oracle Homes. But considering a typical Oracle Home takes about 4 GB or less, this aspect of the suggestion is trivial.

Set audit trail to DB
Set the audit trail to DB by placing the parameter AUDIT_TRAIL = DB in the initialization parameter file during the database creation. Setting this parameter does not start the auditing, because an explicit AUDIT command must be given on the object. But the parameter must be set to a value other than FALSE (the default) for the command to take effect. Being a non-dynamic parameter, the database must be bounced to change the value of AUDIT_TRAIL. To save the trouble and avoid an outage, always set the value to DB, even if you never intend to audit anything. It does not break anything and you will always be ready to audit when the time comes.

Don't use .log
Don't use .log as the extension of redo logs. Someone may run a script to remove all the log files assuming they are redundant and you will end up losing the online redo logs as well, forcing a database recovery. Instead, name them with extension "redo" or "rdo."

Preview RMAN Restore
Preview RMAN Restore to identify all the various backup pieces that will be used in the recovery process without doing an actual recovery. This eliminates any surprises from missing pieces during an actual recovery process.

Create a new Oracle user for clients running on the same server as the DB
The Oracle Database server software also contains the client piece, which allows the clients to connect to the database on the same server. But as a best practice do not use the same user or the software; use a new one. For instance, if "oracle" is the user to install Oracle software, create a new user called, say, "oraapp" and install the client-only software using that user. The user "oraapp" should not be part of the dba or the oinstall group; so this user can't log on to the database as sysdba. Create a new group called "appgrp" and assign the user oraaap to this group. All the application users on the box should also be part of the appgrp group. This way they can use the sqlplus, sqlldr and other executables on the server, but be able to connect as sysdba.

The common practice is to use the client software in the same user as the database software owner; but starting with 10.2, Oracle has changed the security policy that takes away the global execution permissions from the Oracle Home. So the only option is to let app users be part of the dba group or change the permissions on Oracle Home -- both make the database extremely vulnerable.

Friday 15 February 2008

dbms_backup_restore Package

The dbms_backup_restore package is used as a PL/SQL command-line interface for replacing native RMAN commands, and it has very little documentation.

The Oracle docs note how to install and configure the dbms_backup_restore package:

“The DBMS_BACKUP_RESTORE package is an internal package created by the dbmsbkrs.sql and prvtbkrs.plb scripts. This package, along with the target database version of DBMS_RCVMAN, is automatically installed in every Oracle database when the catproc.sql script is run. This package interfaces with the Oracle database server and the operating system to provide the I/O services for backup and restore operations as directed by RMAN.”

The docs also note that “The DBMS_BACKUP_RESTORE package has a PL/SQL procedure to normalize filenames on Windows NT platforms.”

Oracle DBA John Parker gives this example of dbms_backup_restore to recover a controlfile:

declare
devtype varchar2(256);
done boolean;
begin
devtype:=dbms_backup_restore.deviceallocate( type=>'sbt_tape',
params=>'ENV=(OB2BARTYPE=Oracle8,OB2APPNAME=rdcs,OB2BARLIST=ORA_RDCS_WEEKLY)',
ident=>'t1');
dbms_backup_restore.restoresetdatafile;
dbms_backup_restore.restorecontrolfileto('D:\oracle\ora81\dbs\CTL1rdcs.ORA');
dbms_backup_restore.restorebackuppiece(
'ORA_RDCS_WEEKLY.dbf', DONE=>done );
dbms_backup_restore.restoresetdatafile;
dbms_backup_restore.restorecontrolfileto('D:\DBS\RDCS\CTL2RDCS.ORA');
dbms_backup_restore.restorebackuppiece(
'ORA_RDCS_WEEKLY.dbf', DONE=>done );
dbms_backup_restore.devicedeallocate('t1');
end;


Here are some other examples of using dbms_backup_restore:
DECLARE
devtype varchar2(256);
done boolean;
BEGIN
devtype := dbms_backup_restore.DeviceAllocate (type => '',ident => 'FUN');
dbms_backup_restore.RestoreSetDatafile;
dbms_backup_restore.RestoreDatafileTo(dfnumber => 1,toname => 'D:\ORACLE_BASE\datafiles\SYSTEM01.DBF');
dbms_backup_restore.RestoreDatafileTo(dfnumber => 2,toname => 'D:\ORACLE_BASE\datafiles\UNDOTBS.DBF');
--dbms_backup_restore.RestoreDatafileTo(dfnumber => 3,toname => 'D:\ORACLE_BASE\datafiles\MYSPACE.DBF');
dbms_backup_restore.RestoreBackupPiece(done => done,handle => 'D:\ORACLE_BASE\RMAN_BACKUP\MYDB_DF_BCK05H2LLQP_1_1', params => null);
dbms_backup_restore.DeviceDeallocate;
END;
/

--restore archived redolog
DECLARE
devtype varchar2(256);
done boolean;
BEGIN
devtype := dbms_backup_restore.DeviceAllocate (type => '',ident => 'FUN');
dbms_backup_restore.RestoreSetArchivedLog(destination=>'D:\ORACLE_BASE\achive\');
dbms_backup_restore.RestoreArchivedLog(thread=>1,sequence=>1);
dbms_backup_restore.RestoreArchivedLog(thread=>1,sequence=>2);
dbms_backup_restore.RestoreArchivedLog(thread=>1,sequence=>3);
dbms_backup_restore.RestoreBackupPiece(done => done,handle => 'D:\ORACLE_BASE\RMAN_BACKUP\MYDB_LOG_BCK0DH1JGND_1_1', params => null);
dbms_backup_restore.DeviceDeallocate;
END;
/

Wednesday 13 February 2008

Creating Oracle Database Link

Oracle has invested heavily in distributed database technology and the creation of a database link is very straightforward. You specify the database link name, the remote user to connect to, the password for the remote user and the TNS service name for the database link connection:

create public database link
mylink
connect to
remote_username
identified by
mypassword
using 'tns_name';


You can also create a database link to non-Oracle databases, here are steps for a database link to MySQL:

  1. Your first step is having installed the TRANSPARENT GATEWAY (it comes in as of the options when you install Oracle).
  2. You must have a user in the SQL Server.
  3. In the directory \tg4msql\admin look for the file inittg4msql.ora and have the following options:
    HS_FDS_CONNECT_INFO="SERVER=name_server;DATABASE=name_db"
    HS_FDS_TRACE_LEVEL=OFF
    HS_FDS_RECOVERY_ACCOUNT=user_sqlserver
    HS_FDS_RECOVERY_PWD=pass_user_sqlserver
  4. Configure the listener and add the following
    (SID_DESC =
    (PROGRAM = tg4msql)
    (SID_NAME = MSQL)
    (ORACLE_HOME = C:\oracle1)
    )
    )

    and on tnsnames.ora add the following
    MSQL=
    (DESCRIPTION =
    (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = servidor)(PORT = 1521))
    )
    (CONNECT_DATA =
    (SID = MSQL)
    )
    (HS=OK)
    )

    where HS set up as a heterogonous service
  5. Create a link to sql server.
    create database link msql connect to user_sqlserver identified by password using 'MSQL';
  6. You can now use the database link to a foreign database:
    select * from table@msql

Tuesday 12 February 2008

Connect Oracle to SQL Server

In order to connect to SQL*Server from Oracle, you must do several things:

  1. Install ODBC drivers for the SQL*Server database. The drivers are installed on your laptop or on the server that contains the Oracle code tree.
  2. Setup the ODBC connection on your laptop using the Windows ODBC Data Source Administrator
  3. Test the ODBC drivers to ensure that connectivity is made to the non-Oracle database.
  4. Ensure the Global_names parameter is set to False in the Oracle database.
  5. Configure the Hetergeneous services. This consists of creating an initodbc.ora file within the Oracle
  6. Oracle database installation.
  7. Modify the Listener.ora file on the database installation to connect to the Oracle instance and ODBC drivers.
  8. Modify the Tnsnames.ora file to point to the proper code tree.
  9. Reload the listener
  10. Create a database link on the Oracle installation.
  11. Run a Select statement for the Oracle installation using the database link.

Finding Tables References Inside PL/SQL Store Procedure

The Oracle data dictionary tracks the object types referenced in PL/SQL with the dba_dependencies view. To track the dependency among packages and tables, try this dictionary query:

select
referenced_owner,
referenced_name,
referenced_type
from
dba_dependencies
where
name= 'MY_STORE_PROC'
and
owner = 'SCOTT'
order by
referenced_owner, referenced_name, referenced_type;
you can also select the referenced_type, ie. tables

Oracle listener lsnrctl command

Here are lsnrctl command :

C:\>lsnrctl

LSNRCTL for 32-bit Windows: Version 10.2.0.1.0 - Production on 12-PEB-2008 18:56:26

Copyright (c) 1991, 2005, Oracle. All rights reserved.

Welcome to LSNRCTL, type "help" for information.

LSNRCTL> help
The following operations are available
An asterisk (*) denotes a modifier or extended command:

start stop status
services version reload
save_config trace change_password
quit exit set*
show*

LSNRCTL>

The following commands are used to manage the listener:
  • start – Starts the listener with the name specified, otherwise LISTENER will be used. For Windows systems, the listener can also be started from the Control Panel.
  • stop – Stops the listener. For Windows systems, the listener can also be stopped from the Control Panel.
  • status – Provides status information about the listener, including start date, uptime, and trace level.
  • services – Displays each service available, along with the connection history.
  • version – Displays the version information of the listener.
  • reload – Forces a read of the configuration file in order for new settings to take effect without stopping and starting the listener.
  • save_config – Creates a backup of the existing listener.ora file and saves changes to the current version.
  • trace – Sets the trace level to one of the following – OFF, USER, ADMIN, or SUPPORT.
  • spawn – Spawns a program that runs with an alias in the listener.ora file.
  • dbsnmp_start – Starts the DBSNMP subagent.
  • dbsnmp_stop – Stops the DBSNMP subagent.
  • dbsnmp_status – Displays the status of the DBSNMP subagent.
  • change_password – Sets a new password for the listener.
  • quit and exit – Exits the utility.
  • set – Changes the value of any parameter. Everything that can be shown can be set.
  • show – Displays current parameter settings.

Monday 11 February 2008

Preventing Oracle DDL Unauthorized Schema Changes

One of the biggest problems in Oracle are "unexpected" schema changes. In production environments changes are often allowed only during special maintenance times, and changes such as re-analyzing schema statistics and DDL to change table/index structures must be prohibited at other times.

This can be tracked with an Oracle DDL trigger, but the DBA can disable DDL at the object level with a simple script to "disable table lock" syntax:

alter table mbsdba.t_dept disable table lock;

This script could be used to lock all tables within a schema:

connect sys/xxx as sysdba;
spool runme.sql
select "alter table "||owner||"."||table_name||" disable table lock;"
from
dba_tables
where
owner = "mbsdba";

spool off;
@runme.sql

While locked, any attempted schema changes will be rejected
SQL>ALTER TABLE mbsdba.t_dept ADD (NEWCOL NUMBER);

ALTER TABLE mbsdba.t_dept
*

ERROR at line 1:
ORA-00069: cannot acquire lock-- table locks disabled for mbsdba.t_dept

Oracle SQL Sort Merge Join

The use of a sort merge join in Oracle SQL is quite common, especially in cases where there are missing join predicate against one of the tables or a missing index.
In a sort merge join, Oracle must perform full scans on the target tables, sort the keys and join the rows together.
It's important not to confuse a merge join with a merge join cartesian, which is a special case which is usually avoided.
The Oracle docs note these hints for merge joins:

  • Sort merge join - Force a sort merge join (use_merge) The use_merge hint forces a sort merge join.
  • Merge anti join (merge_aj) - Transforms a NOT IN subquery into a merge anti-join.
  • Merge semi-join (merge_sj) - The merge_sj hint is placed into an EXISTS subquery; This converts the subquery into a special type of merge join between t1 and t2 that preserves the semantics of the subquery. That is, even if there is more than one matching row in t2 for a row in t1, the row in t1 is returned only once.
  • Turn off sort merge join (_sortmerge_inequality_join_off) - This hidden parameter will disable a sort merge join in cases where the predicate is an inequality.

Thursday 7 February 2008

ORA-00918: column ambiguously defined

The Oracle docs note this on the ora-00918 error*:

ORA-00918 column ambiguously defined

Cause: A column name used in a join exists in more than one table and is thus referenced ambiguously. In a join, any column name that occurs in more than one of the tables must be prefixed by its table name when referenced. The column should be referenced as TABLE.COLUMN or TABLE_ALIAS.COLUMN. For example, if tables EMP and DEPT are being joined and both contain the column DEPTNO, then all references to DEPTNO should be prefixed with the table name, as in EMP.DEPTNO or E.DEPTNO.

Action: Prefix references to column names that exist in multiple tables with either the table name or a table alias and a period (.), as in the examples above.


*As a note, the ORA-00918 error does not exist in Oracle 10g, according to the Oracle documentation

When ORA-00918 is thrown, you have a column which has been ambiguously defined. If a column name in a join is referenced ambiguously, it exists in multiple tables.

  • Column names which occur in multiple tables should be prefixed when it is referenced by its table name.
  • Columns must be referenced as TABLE.COLUMN or TABLE_ALIAS.COLUM . Oracle documentation which reference ORA-00918 give the following example:
    if tables EMP and DEPT are being joined and both contain the column DEPTNO, then all references to DEPTNO should be prefixed with the table name, as in EMP.DEPTNO or E.DEPTNO.
To correct ORA-00918, references should be prefixed to column names existing in multiple tables (either with the table name or table alias and a period)

ORA-00904: STRING: invalid identifier tips

The Oracle docs note this on the ora-00904 error*:

ORA-00904 string: invalid identifier
Cause: The column name entered is either missing or invalid.

Action: Enter a valid column name. A valid column name must begin with a letter, be less than or equal to 30 characters, and consist of only alphanumeric characters and the special characters $, _, and #. If it contains other characters, then it must be enclosed in double quotation marks. It may not be a reserved word.


*According to Oracle documentation, ORA-00904 does not occur in Oracle 10g

When ORA-00904 occurs, you must enter a valid column name as it is either missing or the one entered is invalid.

To avoid ORA-00904, column names cannot be a reserved word, and must contain these four criteria to be valid:
  • begin with a letter
  • be less than or equal to twenty characters
  • consist only of alphanumeric and the special characters ($_#); other characters need double quotation marks around them

Another important factor in correcting ORA-00904 is remembering to run catproc.sql

You can also check your trace file to find the particular error which is causing the ORA-00904 to occur.

ORA-00304: requested instance_number is busy

The Oracle docs note this on the ora-00304 error:

ORA-00304: requested INSTANCE_NUMBER is busy
Cause: An instance tried to start by using a value of the initialization parameter INSTANCE_NUMBER that is already in use.
Action: Either a) specify another INSTANCE_NUMBER, b) shut down the running instance with this number c) wait for instance recovery to complete on the instance with this number.
You will see ORA 00304 if an INSTANCE_NUMBER parameter value is being used at the time of initializing an Oracle instance
To resolve ORA-00304, you may try one of the three options:

  1. Use a different INSTANCE_NUMBER
    In the initialization file, modify the initialization of the INSTANCE_NUMBER
  2. Shut down the instance number causing the ORA-00304 error
  3. On the instance with the ORA-00304, allow recovery to conclude

Monday 4 February 2008

ORA-00984: Column Not Allowed Here

The Oracle docs note this on the ora-00984 error *

ORA-00984 column not allowed here
Cause: A column name was used in an expression where it is not permitted, such as in the VALUES clause of an INSERT statement.
Action: Check the syntax of the statement and use column names only where appropriate.

An ORA-00984 will be thrown if a column name (like in the VALUES clause of an INSERT statement), is used in an expression where it is not permitted. You may have used a column name in an expression where it is not permitted. Typically, ORA-00984 occurs while including a column name in the VALUES clause of an INSERT statement.

To correct ORA-00984, you simply need to view the syntax of the SQL statement and only use column names where they are appropriate.
You may also find it appropriate to include a character value, in the INSERT statement, instead of the column name.

*Note: ORA-00984 error does not exist in Oracle 10g, according to the Oracle documentation.

Sunday 27 January 2008

Getting Table Details with SQL*Plus

You can use SQL*Plus to provide the following details about a table:

  1. Column Details
  2. PRIMARY KEY
  3. INDEXES
  4. FOREIGN KEYS
  5. CONSTRAINTS
  6. ROWCOUNT
  7. Other Tables That REFER to this Table
  8. PARTITIONED COLUMNS
  9. PARTITIONS
  10. TRIGGERS
  11. DEPENDANTS
Use the following code in SQL*Plus to provide this information:
      SET AUTOTRACE OFF
SET TIMING OFF
COLUMN COMMENTS FORMAT A50
COLUMN column_name FORMAT A35
COLUMN Data_Type FORMAT A15
COLUMN DATA_DEFAULT FORMAT A20
COLUMN "PK Column" FORMAT A35
COLUMN "FK Column" FORMAT A20

UNDEF Owner
ACCEPT Owner PROMPT 'Enter Owner :'

UNDEF Table_Name
ACCEPT Table_Name PROMPT 'Enter Table Name :'


SET HEADING OFF

PROMPT
PROMPT Comments for Table &Table_Name.
SELECT COMMENTS
FROM ALL_TAB_COMMENTS
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND Owner = UPPER('&Owner.') ;

SET HEADING ON

PROMPT
PROMPT Column Details for Table &Table_Name.

SELECT
ROWNUM "Sr No", T.COLUMN_NAME , T.Data_Type , T.DATA_LENGTH,
DECODE(T.Nullable, 'N' , 'NOT NULL' , 'Y', ' ') NULLABLE , T.Data_Default , C.Comments
FROM
ALL_TAB_COLS T , All_Col_Comments C
WHERE
T.OWNER = C.OWNER
AND T.TABLE_NAME = C.TABLE_NAME
AND T.COLUMN_NAME = C.COLUMN_NAME
AND T.TABLE_NAME = UPPER('&Table_Name.')
AND T.Owner = UPPER('&Owner.') ;


PROMPT
PROMPT PRIMARY KEY for Table &Table_Name.

select COLUMN_NAME
FROM ALL_CONS_COLUMNS
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND Owner = UPPER('&Owner.')
AND CONSTRAINT_NAME = ( SELECT CONSTRAINT_NAME
FROM ALL_CONSTRAINTS
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND CONS! TRAINT_T YPE = 'P'
AND Owner = UPPER('&Owner.')
)
ORDER BY POSITION
/

PROMPT
PROMPT INDEXES for Table &Table_Name.

BREAK ON INDEX_NAME ON UNIQUENESS SKIP 1

SELECT I.INDEX_NAME , C.COLUMN_NAME , I.UNIQUENESS
FROM ALL_IND_COLUMNS C , ALL_INDEXES I
WHERE C.INDEX_NAME = I.INDEX_NAME
AND C.TABLE_NAME = I.TABLE_NAME
AND I.TABLE_NAME = UPPER('&Table_Name.')
AND I.Owner = UPPER('&Owner.')
AND C.Table_Owner = UPPER('&Owner.')
AND NOT EXISTS ( SELECT 'X'
FROM ALL_CONSTRAINTS
WHERE CONSTRAINT_NAME = I.INDEX_NAME
AND Owner = UPPER('&Owner.')
)
ORDER BY INDEX_NAME , COLUMN_POSITION
/

CLEAR BREAKS

PROMPT
PROMPT FOREIGN KEYS for Table &Table_Name.

BREAK ON CONSTRAINT_NAME ON TABLE_NAME ON R_CONSTRAINT_NAME SKIP 1
COLUMN POSITION NOPRINT

SELECT UNIQUE A.CONSTRAINT_NAME,
C.COLUMN_NAME "FK Column" ,
B.TABLE_NAME || '.' || B.COLUMN_NAME "PK Column",
A.R_CONSTRAINT_NAME ,
C.POSITION
FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B, ALL_CONS_COLUMNS C
WHERE A.R_CONSTRAINT_NAME=B.CONSTRAINT_NAME
AND B.OWNER=UPPER('&OWNER')
AND A.CONSTRAINT_NAME=C.CONSTRAINT_NAME
AND A.OWNER=C.OWNER
AND A.OWNER = B.OWNER
AND A.TABLE_NAME=C.TABLE_NAME
AND B.POSITION=C.POSITION
AND A.TABLE_NAME LIKE UPPER('&TABLE_NAME')
ORDER BY A.CONSTRAINT_NAME, C.POSITION
/

COLUMN POSITION NOPRINT
CLEAR BREAKS

PROMPT
PROMPT CONSTRAINTS for Table &Table_Name.

SELECT CONSTRAINT_NAME , SEARCH_CONDITION
FROM ALL_CONSTRAINTS
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND Owner = UPPER('&Owner.')
AND CONSTRAINT_TYPE NOT IN ( 'P' , 'R');

PROMPT
PROMPT ROWCOUNT for Table &Table_Name.

SET FEEDBACK OFF
SET SERVEROUTPUT ON
DECLARE N NU MBER ;
V VARCHAR2(100) ;
BEGIN
V := 'SELECT COUNT(*) FROM ' || UPPER('&Table_Name.') ;
EXECUTE IMMEDIATE V INTO N ;
DBMS_OUTPUT.PUT_LINE (N);
END;
/

SET FEEDBACK ON

PROMPT
PROMPT Tables That REFER to Table &Table_Name.

BREAK ON TABLE_NAME ON CONSTRAINT_NAME skip 1

SELECT C.TABLE_NAME , C.CONSTRAINT_Name , CC.COLUMN_NAME "FK Column"
FROM ALL_CONSTRAINTS C
, All_Cons_colUMNs CC
WHERE C.Constraint_Name = CC.Constraint_Name
AND R_CONSTRAINT_NAME = ( SELECT CONSTRAINT_NAME
FROM ALL_CONSTRAINTS
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND CONSTRAINT_TYPE = 'P'
AND Owner = UPPER('&Owner.')
)
AND C.Owner = UPPER('&Owner.')
/

CLEAR BREAKS


PROMPT
PROMPT PARTITIONED COLUMNS for Table &Table_Name.

SELECT COLUMN_NAME , COLUMN_POSITION
FROM All_Part_Key_Columns
WHERE NAME = UPPER('&Table_Name.')
AND Owner = UPPER('&Owner.') ;


PROMPT
PROMPT PARTITIONS for Table &Table_Name.

SELECT PARTITION_NAME , NUM_ROWS
FROM All_Tab_Partitions
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND Table_Owner = UPPER('&Owner.') ;


PROMPT
PROMPT TRIGGERS for Table &Table_Name.

SELECT Trigger_Name
FROM All_Triggers
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND Owner = UPPER('&Owner.') ;

PROMPT
PROMPT DEPENDANTS for Table &Table_Name.

BREAK ON TYPE SKIP 1

SELECT TYPE , NAME
FROM ALL_DEPENDENCIES
WHERE REFERENCED_NAME = UPPER('&Table_Name.')
ORDER BY TYPE ;

CLEAR BREAKS

SET TERMOUT OFF
SET AUTOTRACE ON
SET TIMING ON
SET TERMOUT ON

Monday 21 January 2008

How To : Displaying Column Data Horisontally

Some time you need to create a result set where the rows need to be columns, or vice versa. This commonly requirement can be done by using pivot (or crosstab) query.

1. A simple pivot query can be done by doing the following
2. Add some kind of count or row number to your query, if necessary for the grouping
3. Then use your (revised) original query as a sub-query
4. Use "decode" to turn rows into columns (ie. a "sparse" matrix).
5. Use "max" to "squash" the multiple rows you moved to columns, into single rows. Don't forget to group by.

(Note: it gets more complicated if you don't know how many columns you'll need).

Here is an example of a pivot query. Say you have the following set of data:


And you would like to make DEPTNO be a column. We have 4 deptno's in EMP, 10,20,30,40.
We can make columns dept_10, dept_20, dept_30, dept_40 that have the values that are
currently in the count column. It would look like this:

Note: don't confuse pivot queries with pivot tables. Pivot tables are a different concept, and have different uses (most typically to fill in missing data).

Monday 14 January 2008

Trigger on Insert and Delete

A friend of mine is asking, how to insert into TBL_A, but first you have to insert into TBL_B as master table (TBL_A referencing to TBL_B). We could use trigger on this. Here's two example on creating trigger while insert and delete on a table.

create or replace trigger TBL_A_TRIG_INS
before insert on TBL_A
for each row

begin
insert into TBL_B (ID ,NAME )
values ( :new.ID, :new.NAME );
end;



create or replace trigger TBL_A_TRIG_DEL
after
delete
on TBL_A
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
begin
delete from TBL_B
where ID = :new.ID and NAME = :new.NAME
end;

Tuesday 8 January 2008

Oracle Optimizer Approach Hints

ALL_ROWS
The ALL_ROWS hint explicitly chooses the cost-based approach to optimize a statement block with a goal of best throughput (that is, minimum total resource consumption).

Syntax : /*+ ALL_ROWS */
Example :


conn / as sysdba

set linesize 121
col name format a30
col value format a30

SELECT name, value
FROM gv$parameter
WHERE name LIKE '%optimizer%';

ALTER SYSTEM SET optimizer_mode=RULE SCOPE=MEMORY;

set autotrace traceonly explain

SELECT table_name
FROM dba_tables
WHERE owner = 'SYS'
AND table_name LIKE '%$'
ORDER BY 1;

SELECT /*+ ALL_ROWS */ table_name
FROM dba_tables
WHERE owner = 'SYS'
AND table_name LIKE '%$'
ORDER BY 1;

ALTER SYSTEM SET optimizer_mode=ALL_ROWS SCOPE=MEMORY;
FIRST_ROWS(n)
The FIRST_ROWS hint explicitly chooses the cost-based approach to optimize a statement block with a goal of best response time (minimum resource usage to return first row).

This hint causes the optimizer to make these choices:
  • If an index scan is available, the optimizer may choose it over a full table scan.
  • If an index scan is available, the optimizer may choose a nested loops join over a sort-merge join whenever the associated table is the potential inner table of the nested loops.
  • If an index scan is made available by an ORDER BY clause, the optimizer may choose it to avoid a sort operation.
  • The optimizer ignores this hint in DELETE and UPDATE statement blocks and in SELECT statement blocks that contain any of the following: UNION, INTERSECT, MINUS, UNION ALL, GROUP BY, FOR UPDATE, aggregating function and the DISTINCT operator.
Syntax : /*+ FIRST_ROWS() */
Example :
set autotrace trace exp
SELECT table_name
FROM dba_tables
WHERE owner = 'SYS'
AND table_name LIKE '%$'
ORDER BY 1;
SELECT /*+ FIRST_ROWS(10) */ table_name
FROM dba_tables
WHERE owner = 'SYS'
AND table_name LIKE '%$'
ORDER BY 1;
RULE
Disables the use of the optimizer. This hint is not supported and should not be used.

Syntax : /*+ RULE */
Example :

set autotrace trace exp

SELECT table_name
FROM dba_tables
WHERE owner = 'SYS'
AND table_name LIKE '%$'
ORDER BY 1;

SELECT /*+ RULE */ table_name
FROM dba_tables
WHERE owner = 'SYS'
AND table_name LIKE '%$'
ORDER BY 1;

Monday 7 January 2008

Oracle SQL Hints

/*+ hint */
/*+ hint(argument) */
/*+ hint(argument-1 argument-2) */
All hints except /*+ rule */ cause the CBO to be used. Therefore, it is good practise to analyze the underlying tables if hints are used (or the query is fully hinted.
There should be no schema names in hints. Hints must use aliases if alias names are used for table names. So the following is wrong:

select /*+ index(scott.emp ix_emp) */ from scott.emp emp_alias
better
select /*+ index(emp_alias ix_emp) */ ... from scott.emp emp_alias

Why using hints

It is a perfect valid question to ask why hints should be used. Oracle comes with an optimizer that promises to optimize a query's execution plan. When this optimizer is really doing a good job, no hints should be required at all.
Sometimes, however, the characteristics of the data in the database are changing rapidly, so that the optimizer (or more accuratly, its statistics) are out of date. In this case, a hint could help.
It must also be noted, that Oracle allows to lock the statistics when they look ideal which should make the hints meaningless again.
Hints can be categorized as follows:

  • Hints for Optimization Approaches and Goals,
  • Hints for Access Paths, Hints for Query Transformations,
  • Hints for Join Orders,
  • Hints for Join Operations,
  • Hints for Parallel Execution,
  • Additional Hints

Oracle 10g Release 2 Hint List

Getting a list of Oracle hints for SQL tuning is often difficult. The Oracle hint list is inside the Oracle executable and you can extract the Oracle hint list easily with UNIX commands.

You can use grep and strings to get them directly from the Oracle executable:

strings $ORACLE_HOME/bin/oracle > hints.lst

Here are categorized hint list :
Optimizer Approaches

  • ALL_ROWS
  • FIRST_ROWS(n)
  • RULE
General
  • APPEND
  • CACHE
  • CURSOR_SHARING_EXACT
  • DRIVING_SITE
  • DYNAMIC_SAMPLING
  • MODEL_MIN_ANALYSIS
  • NOAPPEND
  • NO_CACHE
  • NO_PUSH_PRED
  • NO_PUSH_SUBQ
  • NO_PX_JOIN_FILTER
  • NO_XML_QUERY_REWRITE
  • PUSH_PRED
  • PUSH_SUBQ
  • PX_JOIN_FILTER
  • QB_NAME
Access Method Hints
  • FULL
  • INDEX
  • INDEX_ASC
  • INDEX_COMBINE
  • INDEX_DESC
  • INDEX_FFS
  • INDEX_JOIN
  • INDEX_SS
  • INDEX_SS_ASC
  • INDEX_SS_DESC
  • NO_INDEX
  • NO_INDEX_FFS
  • NO_INDEX_SS
Cluster Only Access Method Hints
  • CLUSTER
  • HASH
Join Order
  • LEADING
  • ORDERED
Join Operation
  • NO_USE_HASH (table1 table2)
  • NO_USE_MERGE (table1 table2)
  • NO_USE_NL (table1 table2)
  • USE_HASH (table1 table2)
  • USE_MERGE (table1 table2)
  • USE_NL (table1 table2)
  • USE_NL_WITH_INDEX
Parallel Execution
  • PARALLEL
  • NO_PARALLEL
  • PQ_DISTRIBUTE
  • PARALLEL_INDEX
  • NO_PARALLEL_INDEX
Query Transformation
  • FACT
  • NO_EXPAND
  • NO_FACT
  • NO_QUERY_TRANSFORMATION
  • NO_REWRITE
  • NO_STAR_TRANSFORMATION
  • NO_UNNEST
  • REWRITE
  • STAR_TRANSFORMATION
  • UNNEST
  • USE_CONCAT
Others
  • ANTIJOIN
  • BITMAP
  • BUFFER
  • CARDINALITY
  • HASH_AJ
  • INLINE
  • MATERIALIZE
  • MERGE
  • NO_ACCESS
  • NO_BUFFER
  • NO_MERGE
  • NO_MONITORING
  • NO_PUSH_GSETS
  • NO_PUSH_JOIN_PRED
  • NO_QKN_BUFF
  • NO_SEMIJOIN
  • OR_EXPAND
  • PUSH_JOIN_PRED
  • SEMIJOIN
  • SEMIJOIN_DRIVER
  • SWAP_JOIN_INPUTS
  • USE_ANTI
  • USE_SEMI
Undocumented Optimizer Hints
  • BYPASS_RECURSIVE_CHECK
  • BYPASS_UJVC
  • CACHE_CB
  • CACHE_TEMP_TABLE
  • CIV_GB
  • COLLECTIONS_GET_REFS
  • CPU_COSTING
  • CUBE_GB
  • DEREF_NO_REWRITE
  • DML_UPDATE
  • DOMAIN_INDEX_NO_SORT
  • DOMAIN_INDEX_SORT
  • DYNAMIC_SAMPLING_EST_CDN
  • EXPAND_GSET_TO_UNION
  • FORCE_SAMPLE_BLOCK
  • GBY_CONC_ROLLUP
  • GLOBAL_TABLE_HINTS
  • HWM_BROKERED
  • IGNORE_ON_CLAUSE
  • IGNORE_WHERE_CLAUSE
  • INDEX_RRS
  • LIKE_EXPAND
  • LOCAL_INDEXES
  • MV_MERGE
  • NESTED_TABLE_GET_REFS
  • NESTED_TABLE_SET_REFS
  • NESTED_TABLE_SET_SETID
  • NO_ELIMINATE
  • NO_EXPAND_GSET_TO_UNION
  • NO_FILTERING
  • NO_ORDER_ROLLUPS
  • NO_PRUNE_GSETS
  • NO_STATS_GSETS
  • NOCPU_COSTING
  • OB_NAME
  • OVERFLOW_NOMOVE
  • PIV_GB
  • PIV_SSF
  • PQ_MAP
  • PQ_NOMAP
  • REMOTE_MAPPED
  • RESTORE_AS_INTERVALS
  • SAVE_AS_INTERVALS
  • SCN_ASCENDING
  • SELECTIVITY
  • SKIP_EXT_OPTIMIZER
  • SQLLDR
  • SYS_DL_CURSOR
  • SYS_PARALLEL_TXN
  • SYS_RID_ORDER
  • TIV_GB
  • TIV_SSF
  • USE_TTT_FOR_GSETS

Oracle Optimizer Hints

Optimizer hints can be used with SQL statements to alter execution plans.Hints let you make decisions usually made by the optimizer. As an application designer, you might know information about your data that the optimizer does not know.

For example, you might know that a certain index is more selective for certain queries. Based on this information, you might be able to choose a more efficient execution plan than the optimizer. In such a case, use hints to force the optimizer to use the optimal execution plan.

You can use hints to specify the following:

  • The optimization approach for a SQL statement
  • The goal of the cost-based optimizer for a SQL statement
  • The access path for a table accessed by the statement
  • The join order for a join statement
  • A join operation in a join statement
Note : The use of hints involves extra code that must be managed, checked, and controlled.

Hints provide a mechanism to direct the optimizer to choose a certain query execution plan based on the following criteria:
  • Join order
  • Join method
  • Access path
  • Parallelization
Hints (except for the RULE hint) invoke the cost-based optimizer (CBO). If you have not gathered statistics, then defaults are used. Hints apply only to the optimization of the statement block in which they appear. A statement block is any one of the following statements or parts of statements:
  • A simple SELECT, UPDATE, or DELETE statement.
  • A parent statement or subquery of a complex statement.
  • A part of a compound query.
For example, a compound query consisting of two component queries combined by the UNION operator has two statement blocks, one for each component query. For this reason, hints in the first component query apply only to its optimization, not to the optimization of the second component query.

You can send hints for a SQL statement to the optimizer by enclosing them in a comment within the statement. A statement block can have only one comment containing hints. This comment can only follow the SELECT, UPDATE, or DELETE keyword.
Exception:
The APPEND hint always follows the INSERT keyword, and the PARALLEL hint can follow the INSERT keyword.

The following syntax shows hints contained in both styles of comments that Oracle supports within a statement block.

{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */

or

{DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...

where:
  • DELETE, INSERT, SELECT, and UPDATE are keywords that begin a statement block. Comments containing hints can appear only after these keywords.
  • + causes Oracle to interpret the comment as a list of hints. The plus sign must immediately follow the comment delimiter; no space is permitted.
  • hint is one of the hints discussed in this section. If the comment contains multiple hints, then each hint must be separated from the others by at least one space.
  • text is other commenting text that can be interspersed with the hints.
If you specify hints incorrectly, then Oracle ignores them but does not return an error:
  • Oracle ignores hints if the comment containing them does not follow a DELETE, SELECT, or UPDATE keyword.
  • Oracle ignores hints containing syntax errors, but considers other correctly specified hints within the same comment.
  • Oracle ignores combinations of conflicting hints, but considers other hints within the same comment.
  • Oracle ignores hints in all SQL statements in those environments that use PL/SQL version 1, such as Forms version 3 triggers, Oracle Forms 4.5, and Oracle Reports 2.5. These hints can be passed to the server, but the server ignores them.
The optimizer recognizes hints only when using the cost-based approach. If you include a hint (except the RULE hint) in a statement block, then the optimizer automatically uses the cost-based approach.

Thursday 3 January 2008

Oracle, SQL, PL / SQL Technical Interview Questions

Listed here are Interview Questions for Database Interviews.
This mainly lists Oracle, SQL, PL SQL frequently asked questions in technical Interviews

1. What is DDL, DML ? How are they different?
2. What are different types of joins in SQL?
3. How do you select unique rows using SQL?
4. What is the difference between DELETE and TRUNCATE ?
5. What is the difference between a "where" clause and a "having" clause?
6. What is the difference between "procedure" and "function"?
7. What is the difference between "translate" and "replace" ?
8. How to remove duplicate records from a table?
9. What is a "trigger"?
10.What is the difference between "translate" and "replace"?
11.What is a VIEW?
12.What is the difference among "dropping a table", "truncating a table"
and "deleting all records" from a table
13.Explain new feature of 9i Database ? Explain new feature of 10g Database ?
14.How to use DECODE function?
15.What is “Group by” clause?
16.What are cursors and what are the situations you will use them?
17.What default packages are provided by Oracle?
18.How do you debug a oracle procedure /function?
19.How many triggers are available?
20.How are procedures executed?

Oracle SQL, PL/SQL Interview Question List

These are some Oracle SQL, PL/SQL Interview Question List
1. How do you convert a date to a string?
2. What is an aggregate function?
3. What is the dual table?
4. What are cursors? Distinguish between implicit and explict cursors?
5. Explain how cursors are used by Oracle?
6. What is PL/SQL? Describe the block structure of PL/SQL?
7. What is a nested subquery?
8. What are the various types of queries ?
9. Which of the following is not a schema object : Index, table, public synonym, trigger and package ?
10. What is dynamic sql in oracle?
11. What is the difference between a package, procedure and function?
12. What is the difference between delete, drop and truncating a table?
13. How many triggers are supported in Oracle
14. Are you aware of FLASHBACK concept ? What is it?
15. Describe oracle’s logical and physical structure?
16. What is data dictionary ?
17. What is the use of control files ?
18. How would store XML data in table ? What data type would be used for the columns?
19. Difference between post and commit?
20. Difference between commit and rollback?
21. What are savepoints?
22. What is the Difference between a View and Synonym?
23. How would you fetch system date from oracle?
24. What is the difference between primary key, unique key, foreign key?
25. What is the difference between NO DATA FOUND and %NOTFOUND?
26. What is cursor for loop?
27. What are cursor attributes?
28. What will you use in Query : IN or EXISTS? Why?
29. Explain the difference between a data block, an extent and a segment.?
30. What's the difference between logical and physical I/O?
31. What is an anonymous block?
32. What is a PL/SQL collection?
33. How can you tell if an UPDATE updated no rows?
34. How can you tell if a SELECT returned no rows?

The Difference Between %TYPE and %ROWTYPE

%TYPE and %ROWTYPE are used to define variables in PL/SQL as it is defined within the database. If the datatype or precision of a column changes, the program automically picks up the new definition from the database without having to make any code changes.

The %TYPE and %ROWTYPE constructs provide data independence, reduces maintenance costs, and allows programs to adapt as the database changes to meet new business needs.

%TYPE is used to declare a field with the same type as that of a specified table's column. Example:

DECLARE
v_EmpName emp.ename%TYPE;
BEGIN
SELECT ename INTO v_EmpName FROM emp WHERE ROWNUM = 1;
DBMS_OUTPUT.PUT_LINE('Name = ' || v_EmpName);
END;
/


%ROWTYPE is used to declare a record with the same types as found in the specified database table, view or cursor. Examples:
DECLARE
v_emp emp%ROWTYPE;
BEGIN
v_emp.empno := 10;
v_emp.ename := 'XXXXXXX';
END;
/

DECLARE
v_EmpRecord emp%ROWTYPE;
BEGIN
SELECT * INTO v_EmpRecord FROM emp WHERE ROWNUM = 1;
DBMS_OUTPUT.PUT_LINE('Name = ' || v_EmpRecord.ename);
DBMS_OUTPUT.PUT_LINE('Salary = ' || v_EmpRecord.sal);
END;
/

Oracle DBA Interview Questions

Here are Oracle DBA Questions and Answers in Interview (don't expect too much on this)

1. Explain database instance ?

A database instance (server) is a set of memory structures and background processes that access a set of database files.
The memory structures are used to store most queried data from database. This helps us to improve database performance by decreasing the amount of I/O performed against data file.
The process can be shared by all users.

2. What is parallel server?
Multiple instances accessing the same database (Only in Multi-CPU environments).

3. What is Schema ?
The set of objects owned by user account is called the schema

4. What is an Index ? How it is implemented in Oracle Database ?
An index is a database structure used by the server to have direct access of a row in a table.An index is automatically created when a unique or primary key constraint clause is specified in create table command

5. What is a clusters? Explain
Group of tables physically stored together because they share common columns and are often used together is called Clusters.

6. What is a cluster key ?
The related columns of the tables are called the cluster key. The cluster key is indexed using a cluster index and its value is stores only once for multiple tables in the cluster.

7. What are the basic element of an oracle Database ?
It consists ofone or more data filesone or more control filestwo or more redo log files
The database containsMultiple users/schemasone or more rollback segmentsone or more tablespacesData dictionary tables
User objects (tables,indexes,views etc)
The server that access the database consists of
SGA (Database buffer, Dictionary Cache Buffers, redo log buffers,Shared SQL pool)
SMON
PMON
LGWR
DBWR
ARCH
CKPT
RECO
Dispatcher
User process with associated PGA

8. What is deadlock ? Explain.
Two processes waiting to update the rows of a table which are locked by the other process then deadlock arises.
In a database environment this will often happen because of not issuing proper row lock commands. Poor design of front-end application may cause this situation and the performance of server will reduce drastically.
These locks will be released automatically when a commit/rollback operation performed or any one of this processes being killed externally.

9. What is SGA ?
The System Global Area in a Oracle database is the area in memory to facilitates the transfer of information between users. It holds the most recently requested structural information about the database.

10. What is Shared SQL pool ?
The data dictionary cache is stored in an area in SGA called the Shared SQL Pool. This will allow sharing of parsed SQL statements among concurrent users.

11. What is meant by Program Global Area (PGA) ?
It is area in memory that is used by a Single Oracle User process.

12. What is a data segment ?
Data segment are the physical areas within a database block in which the data associated with tables and clusters are stored.

13. What are the factors causing the reparsing of SQL statements in SGA ?
Due to insufficient Shared SQL pool size

Wednesday 2 January 2008

Oracle 10g UTL_COMPRESS

Oracle 10g includes many PL/SQL enhancements including: utl_compress
The UTL_COMPRESS package provides an API to allow compression and decompression of binary data (RAW, BLOB and BFILE). It uses the Lempel-Ziv compression algorithm which is equivalent to functionality of the gzip utility. A simple example of it's usage would be:

SET SERVEROUTPUT ON
DECLARE
l_original_blob BLOB;
l_compressed_blob BLOB;
l_uncompressed_blob BLOB;
BEGIN
-- Initialize both BLOBs to something.
l_original_blob := TO_BLOB(UTL_RAW.CAST_TO_RAW('1234567890123456789012345678901234567890'));
l_compressed_blob := TO_BLOB('1');
l_uncompressed_blob := TO_BLOB('1');

-- Compress the data.
UTL_COMPRESS.lz_compress (src => l_original_blob,
dst => l_compressed_blob);

-- Uncompress the data.
UTL_COMPRESS.lz_uncompress (src => l_compressed_blob,
dst => l_uncompressed_blob);

-- Display lengths.
DBMS_OUTPUT.put_line('Original Length : ' || LENGTH(l_original_blob));
DBMS_OUTPUT.put_line('Compressed Length : ' || LENGTH(l_compressed_blob));
DBMS_OUTPUT.put_line('Uncompressed Length: ' || LENGTH(l_uncompressed_blob));

-- Free temporary BLOBs.
DBMS_LOB.FREETEMPORARY(l_original_blob);
DBMS_LOB.FREETEMPORARY(l_compressed_blob);
DBMS_LOB.FREETEMPORARY(l_uncompressed_blob);
END;
/

Tuesday 1 January 2008

Oracle DBA : Backup on Tape Drive

For oracle DBA, here are some cases on Tape Drive Backup:

You want to take backup on tape drive but rman always store the backup on a default location

  1. how can we take backup on tape drive, should we have to install any extra softwares for tape drive or rman handle it itself?

    You need thrid party Media managment software like veritas ,omnibackup,tivoli for backing up to tape.If you don't already have Media Management software, you can consider Oracle Secure Backup as a free alternative (assuming you are backing up one server to one tape drive).
  2. how can we set the tape drive as our default location for backup?
    how can we take backup on specified location e.g. d:\backup and how can we set this location as default location for backup?
    To set the tape drive as the default, see Configuring the Default Device Type for Backups.

    If you want the tape drive to be the default backup location, then you'll have to allocate a disk channel to produce backups to d:\backup. You can configure the disk format as CONFIGURE CHANNEL DEVICE TYPE DISK FORMAT 'd:\backups'; and then allocate a disk channel during backup (Manually Overriding Configured Channels).