Showing posts with label Sql*Plus. Show all posts
Showing posts with label Sql*Plus. Show all posts

Saturday, July 17, 2010

Non-Oracle user hits SP2-0642 or SP2-1503/SP2-152 after DST patch

Problem Description
The oracle user (owner of the oracle installation) is able to run sql*plus.

However users different than the owner of the installation (Oracle user is usually the owner) are not able to run SQL*Plus after the DST patches were applied at operating system and database software level. Non oracle users who do not belong under dba unix group it fails with

"SP2-0642: SQL*Plus internal error state 2165, context 4294967295:0:0
Unable to proceed"


Or, after applying DST patch (i.e. Patch 5632264) to Oracle Enterprise Manager 10g Database Control Release 10.2.0.1.0 it fails with following errors.
$ sqlplus /nolog 
SP2-1503: Unable to initialize Oracle call interface
SP2-0152: ORACLE may not be functioning properly
Cause of the Problem
SQL*Plus is unable to access $ORACLE_HOME/oracore/zoneinfo/timezone.dat file. The error message is indicating timezone.dat file is missing from install or inadequate permissions to access $ORACLE_HOME/oracore/zoneinfo directory.

If you do ls -l you will see output like,
$ls -l oracore/zoneinfo/timezone.dat
-rw-r----- 1 oracle dba 161096 Mar 10 20:12 oracore/zoneinfo/timezone.dat
From the permission, it is clear that the users others than oracle and not under dba group do not have privileges on the timezone.dat file, so they are not able to read/write the file above. It needs at least read privileges on other unix group.

Solution of the Problem
To implement the solution, execute the following steps:

1. Manually change the privileges for the $ORACLE_HOME/oracore/zoneinfo directory and files.

$ chmod o+r oracore
$ chmod o+r oracore/zoneinfo/timezone.dat


Alternatively, you can do.
$ cd $ORACLE_HOME
$ chmod -R 755 oracore



2. After you change the permission setting SQL*Plus should be working.
$ sqlplus

After 11.2g new installation invoking sqlplus fails with SP2-1503 SP2-0152

Problem Description
After new Oracle 11.2g installation(64 bit) invoking sqlplus returns SP2-1503 SP2-0152 errors like below.
$ sqlplus
SP2-1503: Unable to initialize Oracle call interface
SP2-0152: ORACLE may not be functioning properly

If you browse to $ORACLE_HOME/oracore/zoneinfo directory and check privilege by using command ls -l you will see a similar output like below,
$cd $ORACLE_HOME/oracore/zoneinfo
$ls -l
total 10092
drwxr-xr-x 2 oracle dba 4096 May 12 17:02 big
drwxr-xr-x 2 oracle dba 4096 May 12 17:02 little
-rw-r--r-- 1 oracle dba 5725 Jun 12 12:02 readme.txt
-rw-r--r-- 1 oracle dba 25681 Jun 16 12:02 timezdif.csv
-rw-r--r-- 1 oracle dba 792894 Jul 10 10:11 timezlrg_10.dat
-rw-r--r-- 1 oracle dba 787272 Jul 10 10:11 timezlrg_11.dat
-rw-r--r-- 1 oracle dba 493675 Jul 10 10:11 timezlrg_1.dat
-rw-r--r-- 1 oracle dba 507957 Jul 10 10:11 timezlrg_2.dat
-rw-r--r-- 1 oracle dba 527717 Jul 10 10:11 timezlrg_3.dat
-rw-r--r-- 1 oracle dba 531137 Jul 10 10:11 timezlrg_4.dat
-rw-r--r-- 1 oracle dba 587487 Jul 10 10:11 timezlrg_5.dat
-rw-r--r-- 1 oracle dba 586750 Jul 10 10:11 timezlrg_6.dat
-rw-r--r-- 1 oracle dba 601242 Jul 10 10:11 timezlrg_7.dat
-rw-r--r-- 1 oracle dba 616723 Jul 10 10:11 timezlrg_8.dat
-rw-r--r-- 1 oracle dba 801410 Jul 10 10:11 timezlrg_9.dat
-rw-r--r-- 1 oracle dba 345637 Jul 10 10:11 timezone_10.dat
-rw-r--r-- 1 oracle dba 345356 Jul 10 10:11 timezone_11.dat
-rw-r--r-- 1 oracle dba 274427 Jul 10 10:11 timezone_1.dat
-rw-r--r-- 1 oracle dba 274900 Jul 10 10:11 timezone_2.dat
-rw-r--r-- 1 oracle dba 286651 Jul 10 10:11 timezone_3.dat
-rw-r--r-- 1 oracle dba 286264 Jul 10 10:11 timezone_4.dat
-rw-r--r-- 1 oracle dba 286310 Jul 10 10:11 timezone_5.dat
-rw-r--r-- 1 oracle dba 286217 Jul 10 10:11 timezone_6.dat
-rw-r--r-- 1 oracle dba 286815 Jul 10 10:11 timezone_7.dat
-rw-r--r-- 1 oracle dba 302100 Jul 10 10:11 timezone_8.dat
-rw-r--r-- 1 oracle dba 351525 Jul 10 10:11 timezone_9.dat

Cause of the Problem
If you look for the ls -l output you will see timezone.dat and timezlrg.dat are not present but multiple versions timezlrg.* and timezone.* are present. The problem happened because there is a choice of timezone versions are available.

Solution of the Problem
To resolve the problem, create links to one of the timezone_nn.dat files. While creating symbolic links you should choose the latest timezone version unless you have a requirement for a specific version.
$ cd $ORACLE_HOME/oracore/zoneinfo
$ ln -s timezone_11.dat timezone.dat
$ ln -s timezlrg_11.dat timezlrg.dat

Saturday, January 30, 2010

SP2-0734: unknown command beginning rest of line ignored

Problem Description
Running any script or SQL or PL/SQL fails with error SP2-0734 unknown command beginning "........" - rest of line ignored..
Following is some example generated while working with script, SQL or Pl/Sql.

Case 01:
Running an oracle script fails as,
SQL> @csminst.sql
SP2-0734: unknown command beginning "csminst.sq..." - rest of line ignored.

Case 02:
Running a procedure fails as,
SQL> my_proc();
SP2-0042: unknown command "my_proc()" - rest of line ignored.

Case 03:
Login to database using sql*plus even login to sql*plus fails with SP2-0042 as below.
$ sqlplus / nolog
SP2-0734: unknown command beginning "yyy..." rest of line ignored.

Case 04:
When trying to purge a table from the recyclebin that is issuing SQL fails with,
SQL> purge table t;
SQL> purge recyclebin;
"SP2-0734: unknown command beginning "purge tabl..." - rest of line ignored."


Solution of the Problem

Case 01 Solution
This is due to the display terminal keyboard configuration of the kill character. Because script is ok and unknown command shown the script name.

The problem is common with unix environment with the display terminal keyboard settings. The sqlplus session had trouble interpreting the "@" sign, because it was assigned in the terminal to the "kill" setting. The csminst.sql script was supposed to be run as "@ csminst.sql" and since the "@" sign had a completely different meaning for this OS session, sqlplus only saw "csminst.sql" and hence it throws error.

There is two solution exists for this type of scenario. One is to change the display terminal keyboard setting of the kill character to something else. For example:

# stty kill ^u

After making this change the script is interpreted correctly and runs as it should.

Another is, run the script using "start" keyword instead of "@" sign.

SQL> start csminst.sql

Case 02 Solution
This is happened because of incorrect way to execute a stored procedure. When calling a PL/SQL stored procedure from SQL*plus you must call it using the EXECUTE (or EXEC) command or via a PL/SQL BEGIN-END block.

Following is the correct examples.

1) EXEC my_proc ();

or

2) BEGIN
my_proc();
END;
/

Case 03 Solution
In this case any invalid entries in glogin.sql file causes this issue. The glogin.sql script gets executed when users invoke sqlplus, even with nolog option.

Check if there is any invalid commands defined in glogin.sql (which usually resides in $ORACLE_HOME/sqlplus/admin).

If not, then check if there is any issue with this file itself. Also rename the glogin.sql file to glogin_bak.sql and try invoking sqlplus again.

Case 04 Solution
This problem happened whenever you connect to the database 10g using SQL*Plus version 9i or lower. The purge command is new in rel 10g, so older versions of SQL*Plus do not recognize it.
To implement the solution, execute the following steps:

1. Connect to the database using SQL*Plus rel 10g, either by logging in directly to the server, or by running SQL*Plus from a 10g client installation.

2. Rerun the purge command. As long as you connect from a 10g version of SQL*Plus, the command will work.

Special Case
Note that, a common SP2-0734 problem happened during controlfile creation. After you have issued ALTER DATABASE BACKUP CONTROLFILE TO TRACE you have generated controlfile script. Whenever you run the script it fails as below.
SQL> CREATE CONTROLFILE REUSE DATABASE "A" NORESETLOGS  NOARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 'D:\APP\ARJU\ORADATA\A\REDO01.LOG' SIZE 50M,
GROUP 2 'D:\APP\ARJU\ORADATA\A\REDO02.LOG' SIZE 50M,
GROUP 3 'D:\APP\ARJU\ORADATA\A\REDO03.LOG' SIZE 50M
-- STANDBY LOGFILE

DATAFILE
'D:\APP\ARJU\ORADATA\A\SYSTEM01.DBF',
'D:\APP\ARJU\ORADATA\A\SYSAUX01.DBF',
'D:\APP\ARJU\ORADATA\A\UNDOTBS01.DBF',
'D:\APP\ARJU\ORADATA\A\USERS01.DBF',
'D:\APP\ARJU\PRODUCT\11.1.0\DB_1\DATABASE\DATA01.DBF',
'F:\MIGRATE_TO_ASM.DBF'
CHARACTER SET WE8MSWIN1252
;

SP2-0042: unknown command "DATAFILE" - rest of line ignored.
SP2-0734: unknown command beginning "'D:\APP..." - rest of line ignored.

This happened due to blank line before the DATAFILE clause and after -- STANDBY LOGFILE , remove that space line as well as remove line -- STANDBY LOGFILE and re run the script, it should be fixed. Fixed one will look like,

SQL> CREATE CONTROLFILE REUSE DATABASE "A" NORESETLOGS  NOARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 'D:\APP\ARJU\ORADATA\A\REDO01.LOG' SIZE 50M,
GROUP 2 'D:\APP\ARJU\ORADATA\A\REDO02.LOG' SIZE 50M,
GROUP 3 'D:\APP\ARJU\ORADATA\A\REDO03.LOG' SIZE 50M
DATAFILE
'D:\APP\ARJU\ORADATA\A\SYSTEM01.DBF',
'D:\APP\ARJU\ORADATA\A\SYSAUX01.DBF',
'D:\APP\ARJU\ORADATA\A\UNDOTBS01.DBF',
'D:\APP\ARJU\ORADATA\A\USERS01.DBF',
'D:\APP\ARJU\PRODUCT\11.1.0\DB_1\DATABASE\DATA01.DBF',
'F:\MIGRATE_TO_ASM.DBF'
CHARACTER SET WE8MSWIN1252
;

Related Documents
http://arjudba.blogspot.com/2008/12/understanding-execution-plan-statistics.html
http://arjudba.blogspot.com/2008/11/formatting-sqlplus-reports.html
http://arjudba.blogspot.com/2008/12/controlling-autotrace-report-in-sqlplus.html
http://arjudba.blogspot.com/2008/12/formatting-sqlplus-reports-part-2.html
http://arjudba.blogspot.com/2008/11/use-of-bind-variables-in-sqlplus.html
http://arjudba.blogspot.com/2008/11/communicate-with-user-through-accept.html
http://arjudba.blogspot.com/2008/11/working-with-sqlplus-scripts.html
http://arjudba.blogspot.com/2008/11/sqlplus-basics-and-tips.html
http://arjudba.blogspot.com/2008/08/error-45-initializing-sqlplus-internal.html
http://arjudba.blogspot.com/2008/05/how-to-see-explain-plan-from-sqlplus.html
http://arjudba.blogspot.com/2008/05/change-prompt-in-sqlplus.html
http://arjudba.blogspot.com/2008/05/how-to-set-environmental-variable-to.html
http://arjudba.blogspot.com/2008/05/what-is-difference-between-and-host.html
http://arjudba.blogspot.com/2008/05/what-is-difference-between-and.html
http://arjudba.blogspot.com/2008/05/what-is-difference-between-and-in.html
http://arjudba.blogspot.com/2008/05/how-can-one-pass-operating-system.html
http://arjudba.blogspot.com/2008/05/where-is-my-column-data-sqlplus-does.html
http://arjudba.blogspot.com/2008/05/automatic-recovery-during-applying-logs.html
http://arjudba.blogspot.com/2008/05/purpose-and-restriction-of-recover.html
http://arjudba.blogspot.com/2008/04/shutdown-modes-in-oracle.html

Tuesday, December 23, 2008

Understanding Execution Plan Statistics

Below is the output of an execution plan statistics.
SQL> set autot trace statistics
SQL> select * from tab;


107 rows selected.


Statistics
----------------------------------------------------------
8 recursive calls
0 db block gets
898 consistent gets
0 physical reads
0 redo size
3459 bytes sent via SQL*Net to client
458 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed

You sometimes want to know what these fields indicates. Below is the details of these fields.

1)recursive calls: For processing of sql statements oracle database maintain internal tables. Sometimes for processing sql statements change is needed in the internal tables and sometimes not. When Oracle Database needs to make a change to these tables, it internally generates an internal SQL statement, which in turn generates a recursive call.


2)db block gets: Number of times a CURRENT block was requested.

3)consistent gets: Number of times a consistent read was requested for a block. This is called the logical reads indicates for processing of a query how many blocks needs to be accessed.

4)physical reads: Total number of data blocks read from disk. This number equals the value of "physical reads direct" + all reads into buffer cache.

5)redo size: For processing of a query total amount of redo generated in bytes.

6)bytes sent through SQL*Net to client: Total number of bytes sent to the client from the foreground processes.

7)bytes received through SQL*Net from client: Total number of bytes received from the client over Oracle Net.

8)SQL*Net round-trips to/from client: Total number of Oracle Net messages sent to and received from the client.
9)sorts (memory):Number of sort operations that were performed completely in memory and did not require any disk writes.

10)sorts (disk):Number of sort operations that required at least one disk write.

11)rows processed: Number of rows processed during the operation.

Controlling the Autotrace Report in sql*plus

In sql*plus with AUTOTRACE command you can see the execution plan of successful SQL DML (that is, SELECT, DELETE, UPDATE and INSERT) statements which is useful for monitoring and tuning the performance of these statements.

You can control the report by setting the AUTOTRACE system variable.

Following is the available AUTOTRACE settings.

1)SET AUTOTRACE OFF: No AUTOTRACE report is generated. This is the default. Result of a query will be displayed on the console as usual.

2)SET AUTOTRACE ON EXPLAIN: The AUTOTRACE report shows the optimizer execution path along with query output and note but does not show statistics.

3)SET AUTOTRACE ON STATISTICS:
The AUTOTRACE report shows the SQL statement execution statistics along with query output but does not display execution plan.

4)SET AUTOTRACE ON: The AUTOTRACE report includes both the optimizer execution path and the SQL statement execution statistics along with query output.

5)SET AUTOTRACE TRACEONLY: Report displays both optimizer execution path as well as execution statistics but does not display query output. If STATISTICS is enabled, query data is still fetched, but not printed.

Sunday, December 21, 2008

Formatting SQL*Plus Reports Part 2

Computing Summary of a column
With combination of BREAK and COMPUTE command you can do several calculations on SQL reports using sql*plus.
Remember the COMPUTE command has no effect without a corresponding BREAK command.

Below is the lists of compute functions of Sql*plus and their effects.

1)SUM: Sum of the values in the column.

2)MINIMUM: Minimum value in the column.

3)MAXIMUM: Maximum value in the column.

4)AVG: Average of the values in the column.

5)STD: Standard deviation of the values in the column.

6)VARIANCE: Variance of the values in the column.

7)COUNT: Number of non-null values in the column.

8)NUMBER: Number of rows in the column.

Let's look at our data,

SQL> select dept_id,name,salary from emp;

DEPT_ID NAME SALARY
---------- ------------ ----------
10 Arju 60000
10 Ershad 22000
10 Dulal 40000
20 Riaz 35000
20 Hasib 60000
30 Raihan 25000

6 rows selected.

Now we wish to compute the total of SALARY by department. To do that use,

SQL> break on dept_id
SQL> compute sum of salary on dept_id
SQL> /


DEPT_ID NAME SALARY
---------- ------------ ----------
10 Arju 60000
Ershad 22000
Dulal 40000
********** ----------
sum 122000
20 Riaz 35000
Hasib 60000
********** ----------
sum 95000
30 Raihan 25000
********** ----------
sum 25000

6 rows selected.


Note that the word sum appears in every break. If you don't want to print sum word then do as,

SQL> COLUMN DUMMY NOPRINT;
SQL> COMPUTE SUM OF SALARY ON DUMMY;
SQL> BREAK ON DUMMY SKIP 1;
SQL> select dept_id DUMMY,dept_id,name,salary from emp;


DEPT_ID NAME SALARY
---------- ------------ ----------
10 Arju 60000
10 Ershad 22000
10 Dulal 40000
----------
122000

20 Riaz 35000
20 Hasib 60000
----------
95000

30 Raihan 25000
----------
25000
6 rows selected.

To compute the salaries just at the end of the report,

SQL> COLUMN DUMMY NOPRINT;
SQL> COMPUTE SUM OF SALARY ON DUMMY;
SQL> BREAK ON DUMMY;
SQL> SELECT NULL DUMMY,DEPT_ID,NAME,SALARY FROM EMP;


DEPT_ID NAME SALARY
---------- ------------ ----------
10 Arju 60000
10 Ershad 22000
10 Dulal 40000
20 Riaz 35000
20 Hasib 60000
30 Raihan 25000
----------
242000

6 rows selected.


To calculate grand total of salary and make it a level do,

SQL> BREAK ON REPORT
SQL> COMPUTE SUM LABEL TOTAL OF SALARY ON REPORT
SQL> select dept_id,name,salary from emp;


DEPT_ID NAME SALARY
---------- ------------ ----------
10 Arju 60000
10 Ershad 22000
10 Dulal 40000
20 Riaz 35000
20 Hasib 60000
30 Raihan 25000
----------
TOTAL 242000

6 rows selected.

To compute the both average and sum of salaries of a department do,

SQL> BREAK ON DEPT_ID
SQL> COMPUTE AVG SUM OF SALARY ON DEPT_ID
SQL> select dept_id,name,salary from emp where dept_id=10;


DEPT_ID NAME SALARY
---------- ------------ ----------
10 Arju 60000
Ershad 22000
Dulal 40000
********** ----------
avg 40666.6667
sum 122000


To see current compute settings,
SQL> compute
COMPUTE sum LABEL 'sum' OF SALARY ON DUMMY
COMPUTE sum LABEL 'TOTAL' OF SALARY ON REPORT
COMPUTE avg LABEL 'avg' sum LABEL 'sum' OF SALARY ON DEPT_ID
To remove all computes definitions,
SQL> clear compute
computes cleared

Sunday, November 30, 2008

Formatting SQL*Plus Reports

Sometimes you may find difficulties while displaying result on SQL*Plus like a column length displayed as a long length and thus does not result a fine output. In this post I will try to show how we can make good looking result displayed on SQL*Plus.

With COLUMN a column can be formatted. For string type data format is specified by A and then length. Like A7 means total column will span to 7 word length. For number data type the format is 99999 where number of 9s decide the length of digits of number data type.
Changing Column Headings
To change the heading of column a,b and c use commands like below. The vertical bar is used if you want to display the columns in a new line.

SQL> COLUMN A HEADING 'FIRST|COLUMN'
SQL> COLUMN C HEADING 'THIRD|COLUMN'
SQL> COLUMN B HEADING 'SECOND|COLUMN' FORMAT A7
SQL> select a,b,c from test1;


FIRST SECOND THIRD
COLUMN COLUMN COLUMN
---------- ------- ------
1 Hi Hi2

Setting the Underline Character
You see the underline character in the above output under heading is set to -. If you want to change it to = then use,

SQL> SET UNDERLINE =
SQL> /


FIRST SECOND THIRD
COLUMN COLUMN COLUMN
========== ======= ======
1 Hi Hi2

Default Display of columns
1)A NUMBER column's width equals the width of the heading or the width of the FORMAT plus one space for the sign, whichever is greater. If you do not explicitly use FORMAT, then the column's width will always be at least the value of SET NUMWIDTH.

BY default the NUMWIDTH is set to 10.

SQL> select 22/7 "This is the pi value" from dual;

This is the pi value
--------------------
3.14285714

SQL> show numwidth

numwidth 10

2)The default width of datatype columns is the width of the column in the database. The column width of a LONG, CLOB, NCLOB or XMLType defaults to the value of SET LONGCHUNKSIZE or SET LONG, whichever is the smaller.

If LONG is set to 80 and LONGCHUNKSIZE is set to 90 then for CLOB database only first 80 character will be shown on Sql*plus by default.

3)The default width and format of unformatted DATE columns in SQL*Plus is determined by the database NLS_DATE_FORMAT parameter. Otherwise, the default format width is A9.

Listing and Resetting Column Display Attributes
1)To list the current display attributes for a given column, use the COLUMN command followed by the column name.

COLUMN column_name

2)To list the current display attributes for all columns, enter just the COLUMN command.

COLUMN

3)To reset the display attributes for a column to their default values, use the CLEAR clause of the COLUMN command as below.

COLUMN column_name CLEAR

4)To reset all column display attributes to their default values enter,

CLEAR COLUMNS


Suppressing and Restoring Column Display Attributes

Though COLUMN command you once format a column and now you want to use the default display attributes for the column, but you don't want to remove the attributes you have defined through the COLUMN command. You can achieve that by,
COLUMN column_name OFF

To restore the attributes you defined through COLUMN, use the ON clause:

COLUMN column_name ON

Printing a Line of Characters after Wrapped Column Values
RECSEP determines when the line of characters is printed;
-you set RECSEP to EACH to print after every line,
-to WRAPPED to print after wrapped lines,
-The default setting of RECSEP is WRAPPED.

RECSEPCHAR sets the character printed in each line.

To print a line of dashes after each wrapped column value, enter:

SET RECSEP WRAPPED
SET RECSEPCHAR "-"


Clarifying Your Report with Spacing and Summary Lines
With the BREAK command you can suppress the duplicate values in a column specified in an ORDER BY clause. If two columns values come in the subsequent rows and you use BREAK on the column then only one will be shown as below.

Note that here I did not use order by clause. You should use order by on the column that you break. If you do not do this, breaks occur every time the column value changes.

SQL> select station_id,uname from users where station_id!=1 and rownum<=10;

STATION_ID UNAME
---------- --------------------------------------------------
4 a.sadat
14 parvez
14 reza
14 voyeger
40 support
71 accounts5
71 bill5
71 chinmoy
71 crash5
71 mubeen5

10 rows selected.

SQL> break on station_id skip 2
SQL> select station_id,uname from users where station_id!=1 and rownum<=10;


STATION_ID UNAME
---------- --------------------------------------------------
4 a.sadat


14 parvez
reza
voyeger


40 support


71 accounts5
bill5
chinmoy
crash5
mubeen5



10 rows selected.

SQL> break on station_id skip page
SQL> /


STATION_ID UNAME
---------- --------------------------------------------------
4 a.sadat

STATION_ID UNAME
---------- --------------------------------------------------
14 parvez
reza
voyeger

STATION_ID UNAME
---------- --------------------------------------------------
40 support

STATION_ID UNAME
---------- --------------------------------------------------
71 accounts5
bill5
chinmoy
crash5
mubeen5

10 rows selected.

To insert n blank lines, use the BREAK command in the following form:

BREAK ON break_column SKIP n

where n can be 1 or 2 or ....
To skip a page, use the command in this form:

BREAK ON break_column SKIP PAGE


You may wish to insert blank lines or a blank page after every row.
To skip n lines after every row, use BREAK in the following form:

BREAK ON ROW SKIP n

To skip a page after every row, use

BREAK ON ROW SKIP PAGE


You can list your current break definition by entering the BREAK command with no clauses:

BREAK


You can remove the current break definition by entering the CLEAR command with the BREAKS clause:

CLEAR BREAKS

Use of bind variables in Sql*plus

Bind variables are variables that are declared inside PL/SQL or a variable in a SQL statement that must be replaced with a valid value.

In the SQL*Plus you can also create bind variable. If you create a bind variable in SQL*Plus, you can use the variable as you would a declared variable in your PL/SQL subprogram and then access the variable from SQL*Plus.

Creating Bind Variables
In order to create bind variable in Sql*plus you have to use variable keyword. To create a bind variable named bind_var as number datatype use,
variable bind_var NUMBER

Displaying Bind Variables

To display all bind variables in the session just use variable keyword.
SQL> variable
variable bind_var
datatype NUMBER

In order to display the value of a particular bind variable use,
SQL> print bind_var
BIND_VAR
----------

Using Bind Variables
To use bind variable first use colon(:) and then give variable name. In order to change values of bind variable you must enter in a PL/SQL block. To change bind variable of bind_var to 10 use,
begin
:bind_var:=10;
end;
/

Saturday, November 29, 2008

Communicate with the user through Accept and Prompt in Sql*plus

With Sql*plus Accept and Prompt command we can take input from users and based on the input we can work. Prompt command will display output and accept command is used to take input from users in to a substitution variable.

Example of Receiving a Substitution Variable Value
1)Creating a script named b.sql. This script will take title from users and will display a title along with salary report.
SQL> ed b
PROMPT Enter a title up to 30 characters
ACCEPT TITLE PROMPT 'Title: '
TTITLE LEFT TITLE SKIP 2
SELECT ID, Designation, max_salary
FROM DESIGNATION
WHERE ID IN (1,2,3);

2)Run the b.sql
SQL> start b

Enter a title up to 30 characters
Title: This is Salary Testing Report

This is Salary Testing Report

ID DESIGNATION MAX_SALARY
---------- -------------------------------------------------- ----------
1 General Manager 100000
2 Asst General Manager 20000
3 Manager 50000

Customizing Prompts for Substitution Variable
This script will take input into a substitution variable and display report based on the input.
SQL> ed c
PROMPT Enter a valid employee ID
ACCEPT ENUMBER NUMBER PROMPT 'Employee ID. :'
SELECT ID,DESIGNATION, MAX_SALARY
FROM DESIGNATION
WHERE ID=&ENUMBER;

SQL> start c
Enter a valid employee ID
Employee ID. :3
old 3: WHERE ID=&ENUMBER
new 3: WHERE ID= 3

ID DESIGNATION MAX_SALARY
---------- -------------------------------------------------- ----------
3 Manager 50000

Friday, November 28, 2008

Working with Sql*plus Scripts

Running Sql Scripts
To run a sql scripts in Sql*plus use @ or @@ or start command. To run a script named C:\test.sql use,
@c:\test
or,
@@c:\test
or,
start c:\test


Define editor and editing sql scripts on command line
Have a look at
Say yes to Sql*Plus Sql*Plus Tips

In addition,
CLEAR BUFFER (CL BUFF): Will clear buffer, i.e delete all lines from the Sql buffer.

To insert a line before line 1, enter a zero ("0") and follow the zero with text.
0 SELECT Username

Placing comments in Sql Scripts
1)Using Sql*plus REMARK command: If a line starts with REMARK rest words of the line are considered as comment and hence ignored to compile. This is applied to single line only.
Example:
REMARK This script will generate the salary history
REM This script is generated on 11/01/2008


2)Using /*...*/: In order to comment multiple lines start with /* and until it gets */ entire commands inside it are considered as comments. With /*...*/ you can also comment a single line.
You must enter a space after the slash-asterisk(/*).
Example:
/* Column Salary for 9999
Column Name for a30
*/


3)Using --: You can use ANSI/ISO "- -" style comments within SQL statements, PL/SQL blocks, or SQL*Plus commands. This comment cannot span multiple lines.
To span it multiple lines start each line with --.
Example:
--This is a comment.

Issues while placing comments in Sql Scripts

SQL*Plus does not have a SQL or PL/SQL command parser.

It scans the first few keywords of each new statement to determine the command type, whether it is SQL, PL/SQL or SQL*Plus.

Comments in some locations can prevent SQL*Plus from correctly identifying the command type, and thus give unexpected results.

Rules
1)Do not put comments within the first few keywords of a statement. Beow is an example. In first case I commented before procedure keyword and thus PL/SQL block terminates before it is expected and in the second case, it is successfully created because of right select for comment.

SQL> create or replace
2 /* This is a comment */
3 procedure test_proc as
4 begin
5 dbms_output.put_line('Test Comment');

Warning: Procedure created with compilation errors.

SQL> end;
SP2-0042: unknown command "end" - rest of line ignored.
SQL> /

Warning: Procedure created with compilation errors.

SQL> create or replace procedure
2 /* This is a comment */
3 test_proc as
4 begin
5 dbms_output.put_line('Test Comment');
6 end;
7 /

Procedure created.

2)Do not put comments after statement terminators (period, semicolon or slash).
Example:
SQL> select sysdate from dual; --This is a comment
2
SQL> /
select sysdate from dual; --This is a comment
*
ERROR at line 1:
ORA-00911: invalid character

3)Don't put statement termination character at the end of the comment. For example,
select sysdate
--This is comment;
from dual;


statement will fail because statement termination occurs in the comments.
SQL> select sysdate from dual; --This is a comment
2
SQL> /
select sysdate from dual; --This is a comment
*
ERROR at line 1:
ORA-00911: invalid character


SQL> select sysdate
2 --This is comment;
--This is comment
*
ERROR at line 2:
ORA-00923: FROM keyword not found where expected

SQL> from dual;
SP2-0042: unknown command "from dual" - rest of line ignored.

However, if we omit semicolon from comment then statement successfully executed.
SQL> select sysdate
2 --This is comment
3 from dual;


SYSDATE--
---------
29-NOV-08

4)Do not use ampersand characters '&' in comments in a SQL statement or PL/SQL
block. Because & is identified as substitution variable unless if you set SET DEFINE OFF to prevent scanning for the substitution character.

Example:
SQL> select sysdate
2 --Comment &
3 from dual;

SP2-0317: expected symbol name is missing

SYSDATE--
---------
29-NOV-08

SQL> set define off
SQL> select sysdate
2 --Comment &
3 from dual;


SYSDATE--
---------
29-NOV-08

Sql*plus Basics and Tips

The Sql Buffer
The Sql buffer stores most recently SQL command or most recently PL/SQL block.

SQL*Plus does not store SQL*Plus commands, or the semicolon or slash characters
you type to execute a command in the SQL buffer.

You can execute the command or block in the SQL buffer using the RUN or /(slash)
commands.

RUN commands displays the command or block in the buffer and then execute it.
/(slash) executes the command or block in the buffer but does not display it.

Below is the example.
A simple SQL command.
SQL> select sysdate from dual;
SYSDATE
---------
29-NOV-08

This one (Setting linesize) is SQL*plus command and hence is not stored in SQL buffer.
SQL> set linesize 100

Invoking list will show SQL buffer, not SQL*plus command.

SQL> list
1* select sysdate from dual

Run will execute the command after displaying it.
SQL> run
1* select sysdate from dual

SYSDATE
---------
29-NOV-08

/(Slash) will not display the command. It will only execute it.
SQL> /

SYSDATE
---------
29-NOV-08

Continuing a Long SQL*Plus Command on Additional Lines
Suppose you want to write a long sql*plus command or a sql command, a long identifier or a long word in the SQL*plus. You can put them in one line by entering hyphen(-) at the end and then entering a carriage return. SQL*Plus displays a right angle-bracket (>) as a prompt for each additional line.

So hyphen(-) in Sql*plus is considered as continuation character. For example to format a long column you can use hyphen in sql*plus.
SQL> column salary format 99,999 -
> heading 'Monthly Salary'

Similarly,
SQL> select 200--
> 100 from dual;


200-100
----------
100
SQL> select 200-
> -100 from dual;


200-100
----------
100
Hyphen at the last is considered as continuation character. So hyphen at the last is ignored. Hence following will return error.
SQL> select 200-
> 100 from dual;

select 200 100 from dual
*
ERROR at line 1:
ORA-00923: FROM keyword not found where expected

Stopping a Command while it is Running
In order to stop displaying a long running output on Sql*plus press CTRL+C.

Displaying output page by page in Sql*plus

Normally whenever we run any SQL comamnd the output of it came all in a row. If the command return 1000 rows then it shows all on the console. You may also could not be able previous output by scrolling. This may be annoying. In order to display output page by page you have to set two variable.

SET PAGESIZE 30 --which will say in a page how many lines will be displayed.
SET PAUSE ON --which will pause the output to display unless you press enter.

Now run sql command like SELECT OBJECT_NAME FROM DBA_OBJECTS; and proceed further after pressing enter. Every new pressing of ENTER keyword will display you a new page.


Saving Changes to database automatically

With the Sql*plus variable AUTOCOMMIT option you can decide when to commit and when to not. By default it is set to OFF which means committing transaction is done whenever you give COMMIT explicitly. If you want committing will happen immediately then invoke,
SET AUTOCOMMIT ON

In order to do committing after 10 DML statements do,
SET AUTOCOMMIT 10
To turn the autocommit feature off again, enter
SET AUTOCOMMIT OFF

Sql*plus Error messages
Sql*plus errors begin will letter SP2.
Like,
SQL> @testing.sql
SP2-0310: unable to open file "testing.sql"

Sql*plus copy command error messages start with COPY.

Tuesday, August 5, 2008

Error 45 initializing SQL*Plus Internal error

If you are executing normal SQL script then review the script. I ran one SQL script and I saw after executing the script at the end it generated Error 45 initializing SQL*Plus Internal error. I review the script and I saw at the end of it there are some spool output. So I deleted that I ran again and it solved the problem.

However there is related oracle bug when fired whenever you run a Sql Script From OCFS. This bug retained from SQL*Plus - Version 9.0.1.0 to 10.1.0.2. When SQL script file is on a OCFS filesystem created on shared device then executing that script from SQL*Plus will fire the bug.

You can reproduce the bug by following steps.

1.Create a test.sql script on OCFS filesystem containing sql:
startup nomount

2. Check that test.sql script is in correct directory:
$ ls -l /ocfs/scripts
total 1
-rw-r--r-- 1 oracle dba 17 Mar 25 03:12 test.sql

3. Invoke SQL*Plus:
$ sqlplus /nolog

SQL*Plus: Release 10.1.0.2.0 - Production on Wed Aug 25 18:17:41 2004
Copyright (c) 1982, 2004, Oracle. All rights reserved.

4. Connect to database:
SQL> connect / as sysdba
Connected.

5. Execute script:
SQL> @/ocfs/scripts/test.sql
Error 45 initializing SQL*Plus
Internal error

Solution of The Problem
If this happens while you execute your script from OCFS then just copy the SQL script file to a local disk and then execute the script.

Saturday, May 31, 2008

How to see Explain Plan from SQL*Plus

Method 1: Autotrace Facility

When the AUTOTRACE setting of SQL*Plus is enabled, SQL*Plus will print an EXPLAIN PLAN and execution statistics after each SQL statement.
Here is an example, where AUTOT is abbreviation of AUTOTRACE

SQL>SET AUTOT ON
SQL>SELECT * FROM TEST WHERE A=1;


A B
---------- ----------
1 USA


Execution Plan
----------------------------------------------------------
Plan hash value: 2109870067

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
Time |

--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 1 (0)|
00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 8 | 1 (0)|
00:00:01 |

|* 2 | INDEX UNIQUE SCAN | SYS_C005994 | 1 | | 0 (0)|
00:00:01 |

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


Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("A"=1)


Statistics
----------------------------------------------------------
147 recursive calls
0 db block gets
26 consistent gets
6 physical reads
0 redo size
439 bytes sent via SQL*Net to client
458 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

To trace the same statement without displaying the query data, enter:

SQL>SET AUTOTRACE TRACEONLY

To off trace issue,
SET AUTOT OFF
Method 2: DBMS_XPLAN Package
SQL>EXPLAIN PLAN FOR select * from test where a=1;
Explained.

SQL>set linesize 140
SQL>SELECT * FROM TABLE( dbms_xplan.display);


PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
Plan hash value: 2109870067

----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 8 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | SYS_C005994 | 1 | | 0 (0)| 00:00:01 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
-----------------------------------------------------

2 - access("A"=1)

14 rows selected.

Thursday, May 29, 2008

Change Prompt in SQL*Plus

Whenever you log on to SQL*Plus it shows you the prompt SQL>. However you can change it for temporary or for permanent.

To change SQL prompt permanently set environmental variable inside glogin.sql.
To set SQL prompt for a particular OS user set it inside login.sql.
To make it temporary set within SQL*Plus. Like,


To change your SQL*Plus prompt to display your connection identifier, enter:

SET SQLPROMPT "_CONNECT_IDENTIFIER > "
dbase >
To set the SQL*Plus command prompt to show the current user, enter

SET SQLPROMPT "_USER > "
ARJU >

To change your SQL*Plus prompt to display your the current date, the current user and the users privilege level, enter:

SET SQLPROMPT "_DATE _USER _PRIVILEGE> "
01-JUN-08 ARJU >

You can also set a variable as you wish
set SQLPROMPT "JUST For Fun>"
JUST For Fun>

Text in nested quotes is not parsed for substitution. To have a SQL*Plus prompt of your username, followed by "@", and then your connection identifier, enter:

SET SQLPROMPT "_USER'@'_CONNECT_IDENTIFIER > "

Related Documents:
-------------------------------------------------------
How to set Environmental variable to SQL*Plus permanently

How to set Environmental variable to SQL*Plus automatically

When SQL*Plus starts up, it looks for a global login script called glogin.sql in the $ORACLE_HOME/sqlplus/admin directory. If found, this script will be executed. If you want to set your SQL*Plus environmental variable like PAGESIZE or LINESIZE or SQLPROMPT then you can set within the file glogin.sql. Then all of the database users who use SQL*Plus will be affected of this site profile glogin.sql.

After checking site profile oracle checks for user profile named login.sql in the user's home. If you want to set environmental variable for a particular Oracle user then you can use user profile named login.sql. Other users of the OS will not be affected. You will create login.sql, put environmental variables inside it and place it to the user's home location.

In the following section I demonstrate the procedure with an example.

AT first I connected to database without any login.sql file. And then it displays prompt as SQL>
-bash-3.00$ sqlplus arju/a

SQL*Plus: Release 10.2.0.1.0 - Production on Sat May 31 23:27:34 2008

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


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

Now I am creating login.sql and put an entry of sql prompt which will show username@database_name SQL>
SQL> !vi login.sql
set sqlprompt "&&_USER@&&_CONNECT_IDENTIFIER SQL>"


SQL>exit

Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

Now connect to database and see the prompt.
-bash-3.00$ sqlplus arju/a
SQL*Plus: Release 10.2.0.1.0 - Production on Sat May 31 23:28:56 2008
Copyright (c) 1982, 2005, Oracle. All rights reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

ARJU@dbase SQL>


Along with connection identifier you set set other environmental variables like pagesize linesize for a user or globally.