SQL Plus How - To's
SQL Plus How - To's
SQL Plus How - To's
Goal
In SQL*Plus, by default the DML (data manipulation language) transaction is committed to the database
upon exit.
Is there a way to rollback the transaction upon exit or prior to exiting the SQL*Plus session if the commit
has not been explicitly defined?
Solution
From a SQL*Plus standpoint, there are 1 of 2 options:
OPTION 1:
... where test1 = a name you wish to rollback to should you want to reverse the changes back to
this point
SQL> rollback;
OPTION 2:
NOTE: If you do not want to be prompted, then set a static name in place of the &rollback_segment
in step 1, like:
3. Then, if you wish to reverse the DML that has not been committed, then before exiting issue the
rollback command:
SQL> rollback;
How to Delete Line Feeds and Carriage Returns from Varchar2 Data?
Goal
How to delete carriage returns and line feeds contained within the varchar2 field data?
Solution
You can perform the following nested replace sql statement using the replace command to delete the
linefeeds and the carriage returns.
SELECT REPLACE (REPLACE (column name, CHR (13), ‘’), CHR (10), '')
FROM tablename;
B- To set it permanently:
1- Modify the $ORACLE_HOME/sqlplus/admin/isqplus.conf file
to add -initial-env for NLS_LANG and NLS_DATE_FORMAT as follow:
<IfModule mod_fastcgi.c>
FastCgiServer /emea/rdbms/32bit/app/oracle/product/9.2.0/bin/isqlplus -initial-env SHLIB_PATH
-initial-env LD_LIBRARY_PATH -initial-env ORACLE_HOME -initial-env ORACLE_SID -initial-env
TNS_ADMIN -initial-env NLS_LANG -initial-env NLS_NCHAR -initial-env NLS_LANG -initial-env
NLS_DATE_FORMAT -initial-env iSQLPlusNumberOfThreads=20 -initial-env
iSQLPlusTimeOutInterval=30
-initial-env iSQLPlusLogLevel=off -initial-env iSQLPlusAllowUserEntMap=none -idle-timeout 3600
</IfModule>
File: when the contents of the input area are executed, the resulting output is saved to a file. You are
prompted to enter the name of the file. As the output is in HTML format, it is useful to give the saved
output file a .htm or .html extension.
1) Invoke iSQL*Plus:
http://host:port/isqlplus
2) In the User Interface, select output=file.
2) Select 'Execute' button.
3) Save the file. This is an html file.
4) Open the html file using your browser.
Goal
This article lists SQL*Plus commands not supported in the iSQL*Plus user interface. Attempting to use
any of the following unsupported commands or command options raises an SP2-0850 error message.
Solution
The following commands have no context in iSQL*Plus and have not been implemented.
ACCEPT PASSWORD
CLEAR SCREEN PAUSE
The following SET command variables have no context in iSQL*Plus and have not been implemented.
The following commands have security issues on the middle tier and have not been implemented.
GET SPOOL
HOST STORE
The following commands are SQL buffer editing commands which are not relevant in iSQL*Plus and
have not been implemented.
Goal
The purpose of this article is to provide a list of general SQL*Plus limits. The limits shown are valid for
most operating systems.
Solution
Item Limit
filename length system dependent
username length 30 bytes
user variable name length 30 bytes
user variable value length 240 characters
command-line length 2500 characters
length of a LONG value entered through SQL*Plus LINESIZE value
LINESIZE system dependent
LONGCHUNKSIZE value system dependent
output line size system dependent
line size after variable substitution 3,000 characters (internal only)
number of characters in a COMPUTE command
500 characters
label
number of lines per SQL command 500 (assuming 80 characters per line
maximum PAGESIZE 50,000 lines
60,000 characters for VMS; otherwise, 32,767
total row width
characters
maximum ARRAYSIZE 5000 rows
maximum number of nested scripts 20 for VMS, CMS, Unix; otherwise, 5
maximum page number 99,999
maximum PL/SQL error message size 2K
maximum ACCEPT character string length 240 Bytes
maximum number of DEFINE variables 2048
Goal
The goal of this document is to provide one way of getting US Eastern Time No Matter of the Time Zone
Location.
Solution
If Oracle 9i or later is used then use the following sql statement:
That gives you a TIMESTAMP. If a regular DATE is needed then CAST it as shown below:
Problem Description
How can you see the SELECT statement used to create a view?
When you try selecting the TEXT field from USER_VIEWS, you are not able to see the entire SELECT
statement.
Problem Solution
In SQL*Plus, you must first execute SET LONG n, where n is an integer value greater than or equal to
the value of the TEXT_LENGTH field in USER_VIEWS.
For example:
You should now be able to see a complete SELECT statement used to create MYVIEW.
Goal
The article is intended to provide information about how to restrict user database instance access from
iSQL*Plus.
You may want to limit the databases instances that users can access in iSQL*Plus to a restricted list.
When restricted database access has been enabled, a dropdown list of available databases is displayed in
place of the Connection Identifier text field on the Login screen. This enables greater security for
iSQL*Plus Servers in hosted environments.
Solution
.<init-param>
.<param-name>iSQLPlusConnectIdList</param-name>
.<param-value>ora10g;ora9i</param-value>
.<description>The database(s) to which iSQL*Plus users are restricted. The list should contain the Oracle
SIDs or SERVICE_NAMEs, separated by a semicolon (;). If there are no entries, database access is not
restricted through iSQL*Plus.</description>
.</init-param>
Entries in the param-value element should be identical to the alias for SERVICE_NAMEs or SIDs set in
your $ORACLE_HOME/network/admin/tnsnames.ora file.
To
How to Output Two Records from a Single Record Depending on the Column
Value?
Goal
One of the column in a table has three valid values e.g. column value (name: cell) is 1, 2 and 3. The value
3 indicates that the record is both 1 and 2.
When you select the records along with other values, you will get all the three values (1, 2 and 3) in select
statement. Now in the output value = 1 or 2 the single is ok. But for value = 3, you want to create two
records that display values 1 and 2 (value for cell).
ID CELL
----- --------
721 1
722 2
723 3
and the required output is as follows :
ID CELL
----- --------
721 1
722 2
723 1
723 2
Fix
Goal
Fix
To prevent SQL*Plus from automatically committing all changes, such as INSERT, UPDATE, or
DELETE command, you can use the 'ROLLBACK' or 'EXIT ROLLBACK' command before exiting.
exit rollback
Goal
Fix
The logic behind this query is that the CUBE is generating 2^n rows where n is the number of arguments
to the CUBE function. In this case the inner subquery generates 2^6 rows i.e. 64 rows which means you
can generate numbers up to 63.
In case you want to generate numbers beyond this range, then you need to add one more argument to the
CUBE which would increase it to 2^7 rows i.e. 128 rows.
The range can be increased by increasing the number of arguments to the CUBE function.
Goal
Fix
2. This will prompt for user password and will show it in hide mode (* instead of password):
SQL> start hide_pswd.sql
SQL> accept hide_password char prompt 'Enter password: ' hide
Enter password: *****
SQL> connect scott/&&hide_password@aliasdb
Connected.
SQL> /
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
Goal
Fix
In order to generate a delimited file output, you need to concatenate columns using the desired delimiter
i.e. comma.
Example:
feedback=off
newpage=none
termout=off
header=off
nvl(to_char(col2),',')
How to Select N-th Highest Value from a Table?
Goal
This document provides the SQL statement which can be used to find the N-th highest or lowest value
from a table column of NUMBER datatype. Also, provides the N-th highest or lowest DISTINCT value of
a table column.
For example:
- select the 5th highest salary record from the EMP table.
- select the 5th highest salary DISTINCT value from the EMP table.
- select the 5th lowest salary record from the EMP table.
- select the 5th lowest salary DISTINCT value from the EMP table.
Fix
SAL
----------
5000
3000
3000
2975
2850 <--- Top 5th RECORD
2450 <--- Top 5th DISTINCT VALUE
1600
1500
1300 <--- Bottom 5th DISTINCT VALUE
1250 <--- Bottom 5th RECORD
1250
1100
950
800
1. B. A method without using MIN () to find the top 5-th record is:
SELECT distinct (temp.sal) FROM EMP temp WHERE 5= (SELECT COUNT
(tmp.sal) FROM EMP tmp WHERE temp.sal<=tmp.sal);
SAL
----------
2850
2. B. A method without using MIN () to find the top N-th DISTINCT VALUE is:
SELECT DISTINCT (temp.sal) FROM EMP temp WHERE 5 = (SELECT COUNT
(DISTINCT (tmp.sal)) FROM EMP tmp WHERE temp.sal<=tmp.sal);
SAL
----------
2450
3. The general syntax to retrieve the N-th RECORD from the BOTTOM is as follows:
3.A. Select MAX(column_name) from (select column_name from table_name
order by column_name ) where rownum<= N;
For example, the following can be used to find the 5th lowest RECORD from the EMP table:
SELECT MAX(sal) from (select sal from emp order by sal) where rownum
<= 5;
MAX(SAL)
----------
1250
3.B. A method without using MAX () to find the bottom N-th RECORD is:
SELECT distinct (temp.sal) FROM EMP temp WHERE 5 = (SELECT COUNT
(tmp.sal) FROM EMP tmp WHERE temp.sal>=tmp.sal);
SAL
----------
1250
4. The general syntax to retrieve the N-th DISTINCT VALUE from the BOTTOM is as follows:
4.A. Select MAX(column_name) from (select distinct column_name from
table_name order by column_name ) where rownum<= N;
For example, the following can be used to find the 5th lowest DISTINCT value from the EMP table:
Select MAX(sal) from (select distinct sal from emp order by sal) where
rownum <= 5;
MAX(SAL)
----------
1300
4.B. A method without using MAX() to find the lowest N-th DISTINCT VALUE is:
SELECT DISTINCT (temp.sal) FROM EMP temp WHERE 5 = (SELECT COUNT
(DISTINCT (tmp.sal)) FROM EMP tmp WHERE temp.sal>=tmp.sal);
SAL
----------
1300
In examples 1.B., 2.B., 3.B., and 4.B., use the following modification to the query:
From
… WHERE 5 = (SELECT COUNT…
To
…WHERE &N = (SELECT COUNT…
This change will cause the following prompt for the user:
Enter value for n: <user puts in value>
Goal
When you start sqlplus in silent mode, you still get the connected message.
Example:
sqlplus -S /nolog
conn /
Connected.
Fix
1. Do not use the "/nolog" option. This is causing 2 connections. It is the second connection that is
echoed. Instead start sqlplus as:
sqlplus -s /
2. If you need the /nolog, then use grep to exclude the Connected line as follows:
Goal
To explain the new predefined variables introduced in 10g and how they can be used to make the
SQL*PLUS Prompt display more informative.
Fix
You can now use substitution variables in the SQL*Plus command-line prompt to display, for example,
the database and server you are connected to, or other information available through a substitution
variable you choose.
_PRIVILEGE contains the privilege level of the current connect. This will be either AS SYSDBA, AS
SYSOPER or blank to indicate a normal connection.
_USER contains the username as supplied by the user to make the current connection. This is the same as
the output from the SHOW USER command.
These variables can be accessed like any other substitution variable. For example, they could be used in
TTITLE, in '&' substitution variables,
They can used in your SQL*Plus command line prompt by using the SET SQLPROMPT command.
For example, to make your prompt always show your username (_USER), the @ symbol, and then your
connection identifier (_CONNECT_IDENTIFIER) during your session, enter:
You can view the predefined variable definitions in the same way as you view other DEFINE definitions,
using the DEFINE command with no arguments, or with the specific argument you wish to display, for
example:
Variable substitution occurs each time SQLPROMPT is SET. If SQLPROMPT is included in glogin.sql,
then substitution variables in SQLPROMPT are refreshed with each login or connect.
You need the 'Select Any Table' privilege to successfully run the following example scripts.
2. To set the SQL*Plus command prompt to show the current user, enter
SQL> SET SQLPROMPT "_USER > "
SCOTT >
3. To change your SQL*Plus prompt to display your the current date, the current user and the users
privilege level, enter:
SQL> SET SQLPROMPT "_DATE _USER _PRIVILEGE> "
17-MAR-04 SCOTT >
4. To change your SQL*Plus prompt to display a variable you have defined, enter:
SQL> DEFINE Instance = Prod
SQL> SET SQLPROMPT Instance> "
Prod>
5. Since 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:
SQL> SET SQLPROMPT "_USER'@'_CONNECT_IDENTIFIER > "
SCOTT@isc101 >
At present there is no predefined variable to display the database you are connected to.You can use the
notes referenced below for the same.
Fix:
After the SQL statement is executed the time needed for processing the
statement is printed into the next line.
Interpretation:
Elapsed: 00:00:00.32
^ ^ ^ ^
| | | |
| | | milliseconds
| | seconds
| minutes
hours
SPECIAL NOTE:
The seconds field will represents the TOTAL TIME in seconds.
Abstract: ELAPSED TIME SHOWS INCORRECTLY FOR DBMS_LOCK.SLEEP VALUES GREATER
THAN 1 MINUTE
The seconds overflow (60 seconds = 1 minute) will not reset the seconds counter
so it's possible that the seconds field gets more than 2 digits (>60)!
To find the actual seconds, the Hours and Minutes must be removed from the total.
Above example:
hours: 1
minutes: 5
seconds: 3909.35 - (1*3600) - (5*60) = 9.32
Converts to:
hours: 1
minutes: 5
seconds: 9
milliseconds: 32
PURPOSE
CHILD PARENT
----- --------------------
E0001 FATHER-JOHN
E0001 MOTHER-NANCY
E0002 FATHER-BLAKE
E0002 MOTHER-SALLY
E0003 FATHER-WILLIAM
E0004 MOTHER-JULIE
• Goal: How to calculate the number of days betweeen two dates excluding weekends
• fact: Embedded SQL
Fix:
eg.
select
(trunc(enddate,'D') - trunc(begdate+6,'D'))
- (((trunc(enddate,'D') - trunc(begdate+6,'D'))/7)*2)
+ decode(to_number(to_char(enddate,'D')),3,1,4,2,5,3,6,4,7,5,0)
+ decode(to_number(to_char(begdate,'D')),2,5,3,4,4,3,5,2,6,1,0)
days
from datetable
/
Remember this is NOT dynamic. You need to reset it when you change instances, i.e. when you use the
connect command to logon to another instance.
To successfully run the above script, you need the Select Any Table privilege.
Trying to do a long select that will ultimately result in 3 lines of output separated by carriage returns.
For Example:
Select 'D',val1, val2, '^M', 'F',val1, val3,'^M','A',val1,val4,'^M'
from value_table.
Pipes will be used instead of comma delimiters and the output will need to be looked like this:
D|val1|val2|valx|
F|val1|val3|valx|
A|val1|val4|valx|
Fix
Basically, carriage return --> CHR(10) but has to be used with the concatenate symbol '||'.
TESTCASE 3 below is probably the closest to what you are looking for:
For Example:
SQL> ed
Wrote file afiedt.buf
1 select empno||','||ename||','||chr(10)||job
2* from emp
SQL> /
TESTCASE DETAILS:
TESTCASE 1:
SQL> ed
Wrote file afiedt.buf
1 select empno||chr(10)||ename||chr(10)
2* from emp
SQL> /
EMPNO||CHR(10)||ENAME||CHR(10)||JOB
------------------------------------------
7369
SMITH
CLERK
7499
ALLEN
SALESMAN
7521
WARD
SALESMAN
EMPNO||CHR(10)||ENAME||CHR(10)||JOB
------------------------------------------
7566
JONES
MANAGER
7654
MARTIN
SALESMAN
7698
BLAKE
EMPNO||CHR(10)||ENAME||CHR(10)||JOB
------------------------------------------
MANAGER
7782
CLARK
MANAGER
7788
SCOTT
ANALYST
...
etc
TESTCASE 2:
==========
SQL> ed
Wrote file a
1 select empno||','||ename||','||job||chr(10)
2* from emp
SQL> /
EMPNO||','||ENAME||','||JOB||CHR(10)
--------------------------------------------------------
7369,SMITH,CLERK
7499,ALLEN,SALESMAN
7521,WARD,SALESMAN
7566,JONES,MANAGER
7654,MARTIN,SALESMAN
7698,BLAKE,MANAGER
7782,CLARK,MANAGER
7788,SCOTT,ANALYST
7839,KING,PRESIDENT
7844,TURNER,SALESMAN
7876,ADAMS,CLERK
EMPNO||','||ENAME||','||JOB||CHR(10)
--------------------------------------------------------
7900,JAMES,CLERK
7902,FORD,ANALYST
7934,MILLER,CLERK
14 rows selected.
TESTCASE 3:
Closest to the format -- D|val1|val2|valx|
-- would be something like this:
SQL> ed
Wrote file afiedt.buf
1 select empno||','||ename||','||chr(10)||job
2* from emp
SQL> /
EMPNO||','||ENAME||','||CHR(10)||JOB
----------------------------------------------------------
7369,SMITH,
CLERK
7499,ALLEN,
SALESMAN
7521,WARD,
SALESMAN
7566,JONES,
MANAGER
...
etc
How to show the values of a column in a row for both previous/current record
Goal
How To show the values of a column in a row for both previous/current record ?
Fix
YRQR PROFIT
--------- ----------
31-DEC-02 10
31-MAR-03 11
30-JUN-03 12
30-SEP-03 12
Following query will show the " profit for current quarter and Last quarter in same row "
Following query will show "Profit in the current quarter and Next quarter in same row. ".
When you query any table in relational database, the datas are represented as row format. That means
each record in the table is represented in row. But to analyze the data the above format would not be
enough , there you need data in 3-dimensional format i.e. to represent in rectangular format ( popularly
know as matrix format )
Where you will have a row attribute, column attribute and cell which shows the values for the
corresponding row and column attribute .
Eg.
Row1
Row2
Row3
Row4
How to achieve the same in sqlplus without using any other tools?
Note :- The same output format can be easily designed thru Oracle Reports writer .
Fix
Here I am showing an example shows the no.of people joined in a department on year basis. The query is
based on Scott.EMP table.
14 rows selected.
select deptno,
sum(decode(to_char(hiredate,'RRRR'),'1980',1,0)) "1980",
sum(decode(to_char(hiredate,'RRRR'),'1981',1,0)) "1981",
sum(decode(to_char(hiredate,'RRRR'),'1982',1,0)) "1982",
sum(decode(to_char(hiredate,'RRRR'),'1987',1,0)) "1987"
from emp
group by deptno
DEPTNO 1980 1981 1982 1987
---------- --------- ---------- ---------- ----------
10 0 2 1 0
20 1 2 0 2
30 0 6 0 0
Which shows the no. of employee joined to departments in the above years.
Note: - The only drawback here is the column can not be added automatically. That means for each
column and corresponding cell values to display, then the column need to be defined in query.
Let us assume a table CUSTOMER with lot of records saved. We want to check the column CUSTID
with a particular format like 99 .So that we can update all records of the table.column in the same format.
Fix
CUSTID
----------
IN-CTC-001
IN-BNG-001
IN-BNG-12
IN-MUM-01
We need to check if any of these records keeps the format 'XX-XXX-999'' .Write the query to get the
result
CUSTID
----------
IN-CTC-001
IN-BNG-001
View the Source Code Of A Procedure
Goal
Is it possible to provide a Grant such that User can view only the source code of Procedure but not
execute it.
Fix
A Grant option would allow the user to execute the Procedure. To allow the User to just view the source
code of the Procedure, try the following:
This way, the user can do a select of the View, and see the source code of the Procedure.
SOLUTION DESCRIPTION:
The following SELECT statement will find and display all duplicate rows in a table, except the row with
the maximum ROWID. The example uses the dept table:
The following statement will delete all duplicate rows in a table, except the row with the maximum
ROWID:
EXPLANATION
Using the pseudo column ROWID is the fastest way to access a row. ROWID represents a unique storage
identification number for a single row in a table (Note: Two rows on different tables but stored in the
same cluster may have the same rowid value).
Duplicate rows which contain only null columns, however, will not be identified by either of the two
methods above.
PROBLEM DESCRIPTION:
You want to create a flat file with the output from a SQL query. When you execute the query, the rows
are wrapped around. How can you prevent this wrap-around?
SOLUTION DESCRIPTION:
To store the SQL query results in a file, you need to enter the SPOOL command in SQL*Plus:
If you do not follow the filename with a period and an extension, SPOOL adds a default file extension to
the filename to identify it as an output file. The default varies with the host operating system. On most
hosts it is LST or LIS.
To create a flat file in SQL*Plus, you first must enter the following:
SET NEWPAGE O
SET SPACE 0
SET LINESIZE 80
SET PAGESIZE 0
SET ECHO OFF
SET FEEDBACK OFF
SET HEADING OFF
After entering these commands, use the SPOOL command as above to create the flat file.
(If the line size is too small, you may set it to a larger number. If you do this, you may need to use
another command 'SET BUFFER xxxx' where xxxx is the same size as the line size).
Solution Description:
Use a format mask without characters. If a table (x) has a date field (a) with two rows
01-jan-96 01:10
01-jan-96 01:20
AVG(TO_NUMBER(TO_CHAR(A,'MMDDYYHHMI')))
---------------------------------------
101960115
The average time of 1:10 and 1:20 gives 1:15 for the hours, date is the same.
Solution Explanation:
1. The following SELECT gives you the seconds past midnight, then displays in hh:mm:ss
2. The following SELECT will convert the seconds past midnight back to display as hh:mm:ss
How to insert & character or special character into Database using SQL*Plus.
• goal: How to insert & character or special character into Database using SQL*Plus.
• fact: Oracle Server - Enterprise Edition
Fix:
Solution 1:
If you are not using substitution variables (&1 &2 &3 etc.) you can do a "SET DEFINE OFF" or "SET
SCAN OFF" to turn off the definition of the ampersand as a substitution variable.
Example:
SQL> SET DEFINE OFF
SQL> INSERT INTO <table_name> VALUES ('AT&T');
/
1 row created
Solution 2:
If you are using substitution variables, set the substitution character to one which will not be encountered
when inserting data.
Example:
SQL> SET DEFINE %
SQL> INSERT INTO <temp_table> VALUES ('AT&T')
/
1 row created.
Solution 3:
If you precede the special character with a backslash and the ESCAPE setting in SQL*Plus is set to ON,
then SQL*Plus will understand the special character following the escape symbol is to be treated as a
regular character.
Example:
SQL>set escape on
SQL>show escape
escape "\" (hex 5c)
SQL> INSERT INTO temp_table VALUES ('select * from emp where ename =
\& 1');
1 row created.
Problem Explanation:
Example 1
When you issue either of the following SELECT statements:
Example 2
Solution Description:
Example 1
---------
SQL> SELECT 'test' || CHR(39) || 'case' result
2> FROM dual;
RESULT
---------
test'case
Example 2
---------
SQL> SELECT CHR(39) FROM dual;
C
-
'
Solution Explanation:
ASCII('''')
-----------
39
Solution Description:
1. Enclose every character string in single quotes. The single quote is a string delimiter.
2. Inside a string literal, use two consecutive single quotes to create a literal single quote.
Example 1
---------
6 single quotes: 'test' || '''''' || 'case' ---> test''case
8 single quotes: 'test' || '''''''' || 'case' ---> test'''case
Hence:
The two single quotes in the middle define the single quote. The outside single quotes are the single
quotes that must surround a string.
Example 2
---------
SQL> SELECT '''' FROM dual;
'
-
'
Example 3
---------
SQL> SELECT 'test' || '''' || 'case' result
2> FROM dual;
RESULT
---------
test'case
b. To place single quotes around a character string, enclose the character string within 3 single quotes: '''
At the start of a character string: the first single quote defines the start of the character string; It is one
of the two single quotes that surround the string. The second and third single quotes define the literal
single quote.
At the end of the character string: the first and second single quotes define the literal single quote.
The third single quote closes the character string; it is the other single quote that surrounds the string.
Example 4
---------
SQL> SELECT '''character string in quotes''' result
2> FROM dual;
RESULT
----------------------------
'character string in quotes'
Solution Explanation:
More examples:
Example 5
---------
SRW.DO_SQL('SELECT DECODE(dname, ''NONE'', NULL, ''A'')
FROM dept
WHERE deptno = 10');
Example 6
---------
DECLARE
a VARCHAR2(200);
q CHAR(1) := '''';
BEGIN
a := '''this is a ' || q || 'quoted'' string' || q;
END;
How can a user perform a case insensitive match using the LIKE comparison operator?
Problem Explanation:
The field in a table may be entered in different cases, for example, 'MacDonald' and MACDONALD' -
how can a single SQL query using the LIKE operator find all occurrences of the name MacDonald.
Solution Description:
You can use the UPPER () function to perform a case insensitive match as in the following condition;
For example, to find an employee name in a string beginning with the letters 'SM' -
SQL > select * from emp where UPPER (ename) like 'SM%' ;
Solution Explanation:
The UPPER function converts the ename field results in the searched column to upper case. For example
the strings 'smith' and 'Smith' and 'SMITH' will all become 'SMITH'.
Problem Explanation:
When moving data between different software products, it is sometimes necessary to use a "flat" file ( an
operating system file with no escape characters, headings, or extra characters embedded ).
Solution Description:
For example:
DEPTNO||CHR(9)||DNAME
-------------------------------------------------------
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS
The CHR() SQL character function is used to embed the TAB in the query text.
DEPTNO||','||DNAME
-------------------------------------------------------
10,ACCOUNTING
20,RESEARCH
30,SALES
40,OPERATIONS
To send your query results to a file, use the following SQL*Plus SET commands before running your
query:
SPOOL OFF
SET TERMOUT ON
Solution Explanation:
SQL*Plus versions 3.0.x and 3.1.x do not have a SET command to specify a column separator to
delineate text between columns.
NOTE:
The result of concatenating two character strings is another character string. If both character strings are
of datatype CHAR, the result has datatype CHAR and is limited to a maximum result of 255 characters.
If either string is VARCHAR2, the result has datatype VARCHAR2 and is limited to a maximum result
of 2000 characters.
Solution Description:
Use the SQL*Plus 3.2.x COLSEP SET command.
For example:
To send your query results to a comma delimited flat file, use the following SQL*Plus commands:
SPOOL OFF
SET TERMOUT ON
Solution Explanation:
SQL*Plus 3.2.x has the COLSEP SET command. Previous versions of SQL*Plus did not have COLSEP.
This solution will send the query results to a file, with the text printed between the SELECTed columns as
specified by the SET COLSEP command.
If the COLSEP variable contains blanks or punctuation characters, you must enclose the text with single
quotes.
The SQL script below when executed will produce a second .SQL file for the table so that the listed table
output will have comma's between the columns.
REM
*********************************************************************
*****
REM COMMA.SQL
REM ------
REM Generate SELECT statements using Catalog tables
REM
REM Usage: @COMMA tablename outputfilename
REM
REM tablename: Any table name (standard SQL wildcards accepted, e.g.
% for all)
REM outputfilename: Target SQL file name (no extension, .SQL
REM extension supplied automatically
REM
*********************************************************************
*
SET FEEDBACK OFF
SET VERIFY OFF
SET TERMOUT OFF
SET PAGES 999
SET HEADING OFF
SELECT
table_name tabname
, 1 seqno
, 0 seq2
, 'SELECT ' txt
FROM
user_tables
WHERE table_name LIKE UPPER('&1')
UNION
SELECT
table_name tabname
, 2 seqno
, column_id seq2
, DECODE(column_id
,1,''
,'||'',''||')||column_name txt
FROM
user_tab_columns
WHERE table_name LIKE UPPER('&1')
and exists (
select 1
from user_tables
where user_tables.table_name = user_tab_columns.table_name )
UNION
SELECT
table_name
, 3 seqno
, 0 seq2
, 'FROM '||table_name||';' txt
FROM
user_tables
WHERE table_name LIKE UPPER('&1')
ORDER BY 1,2,3
SPOOL &2..sql
//
SPOOL OFF
SET FEEDBACK ON
SET VERIFY ON
SET TERMOUT ON
SET HEADING ON
How to Query top "N" rows ordered by a column
Problem Description:
What SQL SELECT statement do you use to retrieve the top "n" rows ordered by a particular "column"?
Problem Explanation:
Solution Description:
To return exactly "n" rows ordered by a column, create a query similar to the following:
SELECT *
FROM table A
WHERE n >= (SELECT COUNT(*)
FROM table B
WHERE B.column >= A.column)
ORDER BY column DESC;
where "n" is the number of rows to be retrieved and ordered, "table" is the name of the table and
"column" is the name of the column.
The first SELECT statement controls the number of rows, while the nested, second SELECT statement
controls the condition.
The query returns the first "n" ordered rows. If n=10 and Rows 8-12 share the same column value, this
only return Rows 9 and 10. The above SELECT statement does not take duplicate column values into
consideration.
Solution Explanation:
To return any row whose column value is one of the top "n" ordered column values, create a query similar
to the following:
SELECT *
FROM table A
WHERE n >= (SELECT COUNT (DISTINCT column)
FROM column B
WHERE B.column >= A.column)
ORDER BY column DESC;
Specifying DISTINCT return all rows whose column (e.g. sal) value falls into one of the top "n" values.
Hence, the query returns more than "n" rows when several rows share the same column value.
How do you convert a character field into a date format without losing the century
data?
Problem Description:
When you convert a character field into a date field, the century information is lost. How do you convert
a character field into date format without losing the century data?
Solution Description:
To retain the four digit century information, you must convert the date field back into a character string.
Answer
Set SQLPATH environment variable. Add all the directories you want SQL*Plus to search for the SQL
scripts, each separated by a semicolon.
Example:
SQLPATH = C:\ORANT\DBS;C:\APPS\SCRIPTS;C:\MYSCRIPTS;
In Windows environment, if you are using 32-bit SQL*Plus then set this variable in the Registry, or if you
are using 16-bit SQL*Plus then set this variable in the file Oracle.ini
You cannot use SYSDATE or USER, to get the SYSDATE, USER over DBLINK due to a known
restriction with these functions. For this, you can use the following workaround:
Step-1:
On the remote machine, populate a table with the SYSDATE, USER, values using a stored procedure on
the remote machine.
CREATE TABLE db_table (mydate DATE);
CREATE OR REPLACE PROCEDURE db_date as mydate date;
BEGIN
DELETE FROM db_table;
SELECT SYSDATE INTO mydate FROM DUAL;
INSERT INTO db_table VALUES (mydate);
END;
Step2:
On local machine, select the data from the table which has been populated using the stored procedure.
EXECUTE db_date@dblink
SELECT mydate FROM db_table@dblink;
You can execute any SQL script using the SQL*Plus command in a batch file. The format of the
command is as follows:
SQL*PlusExecutable USERNAME/PASSWORD@CONNECT_STRING Sqlscript
For Example:
Plus31 scott/tiger@orcl @c: \script.sql
will execute the script script.sql on 'c' drive.
To retrieve the time information, use the TO_CHAR function with a format mask.
Examples:
SELECT To_Char(datecolumn, 'DDMONYY HH24:MI:SS') FROM mytable;
:global.hi := To_Char(:time1, 'DDMONYY HH:MI:SS');
The data returns in the following format:
01SEP94 15:01:01
You can skip a page in SQL*Plus reports by making use of the following statement:
BREAK ON X SKIP PAGE;
COMPUTE SUM OF Y ON X;
SELECT fld1,fld2
FROM tab1,tab2
WHERE x=y
GROUP BY fld1,fld2 ORDER BY fld1;
1. SQL comment delimiters (/*........*/)
EX: SQL> select ename /*this is a comment
delimiter example*/ from /*This is
another example*/ emp;
2. REMARK Begins a remark in a command file.
Must appear at the beginning of a line and
ends at the end of the line.
A line cannot contain both a remark and
a command.
For example: get rem.sql
1 Rem This is an example of how REM is used.
2 Column sal format $99,999.99 heading
3 'Monthly|salary'
4 Compute sum od sal on deptno
5 Rem This sql script will total the salaries
6 Rem of all employees in each department
7 Select deptno, ename, sal from emp
8 order by deptno;
How do I include the current date and time in a SQL*Plus report heading?
The following SQL*Plus command file segment shows how to put the current date into a variable and
then include that variable in the title. To get the time, just change the mask in the to_char function to
include that as well.
COLUMN SYSDATE new_value today
SELECT To_Char(SYSDATE,'mm/dd/yy') "sysdate" FROM DUAL
/
TTITLE left today center 'MY HEADING OR TITLE' skip 2
The use of "new_value" shown here applies in general to any value selected into a column specified in the
COLUMN xxx NEW_VALUE command. It can be used to display various data in the title of a report.
How To Trim Lines When Spooling
To remove trailing blanks at the end of each line enter the following statement on the command prompt
before the spool command:
SQL> set trimspool on
How to insert ‘&’ character or special character into Database using SQL*Plus
Solution 1:
If you are not using substitution variables (&1 &2 &3 etc.) you can do a "SET DEFINE OFF" or "SET
SCAN OFF” to turn off the definition of the ampersand as a substitution variable.
Example:
SQL> SET DEFINE OFF
SQL> INSERT INTO <table_name> VALUES ('AT&T');
/
1 row created
Solution 2:
If you are using substitution variables, set the substitution character to one which will not be encountered
when inserting data.
Example:
SQL> SET DEFINE %
SQL> INSERT INTO <temp_table> VALUES ('AT&T')
/
1 row created.
Solution 3:
If you precede the special character with a backslash and the ESCAPE setting in SQL*Plus is set to ON,
then SQL*Plus will understand the special character following the escape symbol is to be treated as a
regular character.
Example:
SQL>set escape on
SQL>show escape
escape "\" (hex 5c)
SQL> INSERT INTO temp_table VALUES ('select * from emp where ename = \&
1');
1 row created.
First pay attention the database you use is able to deal with the special characters you want to insert. That
means you have to check if the special character is included in your database characterset.
Here just an example how to insert these special characters:
Assume you want to insert the following sample string, consisting of several single characters, which are
concated to one string.
-Ob?''!#*)EBK+`#a"^?#c\QH'
To be able to do this, mask each single ' (single quote) with just one preceeding '(single quote).If just two
''(two single quotes) signs have to be inserted use four '''' (four single quotes):
1 row created.
A
--------------------------
-Ob?''!#*)EBK+`#a"^?#c\QH'
Be aware of the characters (' at the beginning and the characters ') at the end of the string you want to
insert.
Output:
SQL> select * from vv;
PRODUCT ATTR1
---------------- ----------------
product_1 att_12
product_1 attr_11
product_1 attr_13
product_2 att_22
product_2 attr_21
product_2 attr_23
product_3 att_32
product_3 attr_31
product_3 attr_33
1. Select Run from the the Start menu and then enter regedit in the Open field and Click OK to start the
registry Editor.
2. Navigate to HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0.
Note:If you have more than one Oracle installation, you must select the HOME entry associated
with the Windows GUI you want to change. HOME0 is the registry entry for an Oracle installation. A
subsequent Oracle installation will have the registry entry HOME1 and the next HOME2 and so on.
Changes only affect a SQL*Plus Windows GUI started from the associated Oracle installation,
so you can use different settings for each Oracle installation.
3. Click New String Value in the Edit menu. A new string value, with the default name, NewValue #1 is
created at the bottom of the right pane of the Registry Editor. The default name of the new string value is
selected ready for you to replace with the name you want.
4. Enter SQLPLUS_FONT as the name of the new font face string value.If you miskey the name or
inadvertently enter it in mixed or lower case, you can edit the name by selecting Rename from the Edit
menu.
5. Click Modify from the Edit menu or press Enter again to display the Edit String dialog.
6. Enter the font name you want to use, such as Courier New, in the Value Data: field. SQL*Plus will
use the new font the next time you start the SQL*Plus Windows GUI.
Modify Password and Suppressing Typed Password in SQLPLUS
Customer needs to select from a table and display only a limited number of records. Example would be
select all Smiths from address table, but only display the first 10 or what ever.
Solution Description
Solution 1 (simple)
SQL> select empno from emp where empno like '%7%' and rownum <= 10;
EMPNO
7369
7499
7521
7566
7654
7698
7782
7788
7839
7844
10 rows selected.
Solution 2
SQL> l
1 declare
2 v_counter number(3):=+0;
3 v_empno emp.empno%type;
4 cursor emp_cursor is
5 select empno
6 from emp
7 where empno like '7%';
8 begin
9 open emp_cursor;
10 loop
11 exit when emp_cursor%notfound;
12 fetch emp_cursor into v_empno;
13 v_counter := v_counter +1;
14 exit when emp_cursor%notfound or v_counter > 10;
15 dbms_output.put_line(v_empno ||' ' || v_counter);
16 end loop;
17 close emp_cursor;
18* end;
SQL> /
7369 1
7499 2
7521 3
7566 4
7654 5
7698 6
7782 7
7788 8
7839 9
7844 10
PL/SQL procedure successfully completed.
Solution 3
set serveroutput on
accept select_info prompt 'please enter select: '
accept where_info prompt 'please enter where: '
declare
v_counter number(3):=+0;
v_&select_info emp.&select_info%type;
cursor emp_cursor is
select &select_info
from emp
where &select_info like &where_info;
begin
open emp_cursor;
loop
exit when emp_cursor%notfound;
fetch emp_cursor into v_&select_info;
v_counter := v_counter +1;
exit when emp_cursor%notfound or v_counter > 10;
dbms_output.put_line(v_&select_info ||' ' || v_counter);
end loop;
close emp_cursor;
end;
/
SQL*Plus users sometimes want to have rows numbered in a sorted order. This can't be achieved using
the ROWNUM pseudo column, since the ordering is done after the values for ROWNUM had been
assigned to rows as they were selected in random order.
SQL> select ename, rownum from emp;
ENAME ROWNUM
ALLEN 1
JONES 2
BLAKE 3
CLARK 4
KING 5
ADAMS 6
JAMES 7
FORD 8
SQL> select ename, rownum from emp order by ename;
ENAME ROWNUM
ADAMS 6
ALLEN 1
BLAKE 3
CLARK 4
FORD 8
JAMES 7
JONES 2
KING 5
Solution Explanation
SQL> select A.ename, count(*) position
2 from emp A, emp B
3 where A.ename > B.ename
4 or A.ename = B.ename and A.empno >= B.empno
5 group by A.empno, A.ename
6 order by A.ename, A.empno;
ENAME POSITION
ADAMS 1
ALLEN 2
BLAKE 3
CLARK 4
FORD 5
JAMES 6
JONES 7
KING 8
This method works by counting the number of records that a particular record is superior than (or equal
to) in alphabetical order of employee name. The empno column acts as a unique key to discern between
records in case identical names occur in the table. This would not be an efficient method against tables
with large numbers of rows.
Another alternative is to create an index on the order column, and include a meaningless where clause to
force use of the index.
SQL> create index sort on emp (ename);
Index created.
SQL> select ename, rownum from emp where ename > ' ';
ENAME ROWNUM
ADAMS 1
ALLEN 2
BLAKE 3
CLARK 4
FORD 5
JAMES 6
JONES 7
KING 8
The where clause in the query forces SQL*Plus to use the index created on the ename column, and since
the index is used, the rows are returned in ascending order. Since this method depends on the inherent
order of the index, it cannot be used to return rows numbered in descending order. The last method
presented takes advantage of a feature of the database kernel optimizer.
SQL> select rownum, ename
2 from emp , dual
3 where emp.ename = dual.dummy (+);
ROWNUM ENAME
1 ADAMS
2 ALLEN
3 BLAKE
4 CLARK
5 FORD
6 JAMES
7 JONES
8 KING
The optimizer evaluates the outer join in this example by using a sort/merge join, which results in the
desired sorted order.
PROBLEM:
Your label is missing when doing computes of the first column on a report break. In other words,
suppose you do the following in SQL*Plus:
SQL> break on report
SQL> compute count of deptno on report
SQL> select * from dept;
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
4
Notice the lack of the 'count' label. This happens in report breaks where the computation is performed on
the first column. Normally, the compute labels for a report break always appear in the first column. For
example, if I had performed the count computation on the second column, DNAME, I would have gotten:
SQL> clear computes
Computes cleared
SQL> compute count of dname on report
SQL> select * from dept;
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
count 4
In this case, no computation is performed on the first column so SQL*Plus is free to place the "count"
label in the first column.
RESOLUTION:
The following approach was proposed: use a "dummy" first column to hold the compute label when
you want a compute of the first column on a report break. Here's how it works with our original example:
SQL> clear computes
computes cleared
SQL> clear breaks
breaks cleared
SQL> break on report
SQL> compute count of deptno on report
SQL> col summary format a7
SQL> select ' ' summary, dept.* from dept;
SUMMARY DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
count 4
Thus, we create a dummy left most column named SUMMARY (or whatever is appropriate) to hold the
"count" label. Notice that as the first element of the SELECT list we specify the constant expression ' ' (a
blank string) and give it a column alias of SUMMARY.
Purpose
The purpose of this article is to demonstrate how to make only one connection attempt to the database and
then exit so SQL*Plus does not bring up the username prompt again.
This technique can then be used in scripts or batch files to automatically handle failing SQL*Plus
connections e.g. In backup scripts or batch jobs.
ALTER,
AUDIT,
CREATE,
DELETE,
DROP,
GRANT,
INSERT,
LOCK,
NOAUDIT,
RENAME,
REVOKE,
SELECT,
UPDATE,
VALIDATE.
2. When the user SCOTT tries to execute the command SELECT he will obtain the error:
SQL-script (t1.sql)
set pagesize 0
set feedback off
select 'Number Name' from dual;
select '---------- -------' from dual;
select empno, ename from emp
/
SQL> @t1
=> Result:
Number Name
---------- -------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
Concatenate the ASCII value CHR (10) in between the data where the carriage return is required.
E.G. INSERT INTO <TABLE NAME> VALUES ('HELLO'||CHR (10) ||'HOW ARE YOU')
The above insert statement will insert into the table as two separate lines.
Example:-
Create table test as below.
A typical scenario would be if a file is created with multiple columns piped together placing a carriage
return (CHR(10)) at the end of each record. The carriage return is placed at the end of the record length,
set by LINESIZE, instead of immediately following the last column. Use SET TRIMSPOOL ON to have
the carriage return follow the last column.
Example:
spool <filename>
set linesize 100;
set heading off;
set trimspool on
select dname||'|'||loc||'|'||chr(10) from dept; --carriage return after
last ¿|¿ character
spool off
SELECT '&1'
FROM sys.dual;
To create a flat file from within SQL*Plus, use the following SET commands in SQL*Plus:
SQL*Plus stores all information displayed on the screen after the SPOOL command is entered, in the
specified file. If no file extension is specified, SPOOL add a default file extension to the filename to
identify it as an output file, usually LIS or LST, depending on host operating system.
SQL*Plus continues to spool information to the file until spooling is turned off using the following
command:
How To Remove The Default Single Space Between Fields From The Output Of a
SELECT Statement In SQL*Plus
This can be done using the SET COLSEP command.
When the SQL*Plus setting WRAP is set to OFF and rows need to be displayed which are larger then the
setting of LINESIZE the message 'rows will be truncated' will be reported.
Use the command SET LONG <n>, where <n> is the max length of the column that will be showed.
Example:
SQL> SET LONG 500