19
#!/bin/sh

echo "Please enter evaluate database username"
read eval_user
echo "Please enter evaluate database password"
read eval_pass
echo "Please enter the database name"
read db_name

LOGFILE=shell_log.txt

$ORACLE_HOME/bin/sqlplus -s /nolog <<-EOF>> ${LOGFILE}
connect $eval_user/$eval_pass@$db_name
WHENEVER OSERROR EXIT 9;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
DBMS_OUTPUT.put_line('Connected to db');
EOF

if [ $? != 0 ]
then 
echo "The upgrade script failed. Please refer to the log results.txt for more information"
echo "Error code $?"
exit 0;
fi

I am entering garbage values trying to force this script to fail. But, annoyingly, it keeps moving ahead without any mention of any error code. What else needs to be done here?

roymustang86
  • 8,054
  • 22
  • 70
  • 101
  • Which OS user account are you running under? What database does the script login to? – APC Feb 11 '13 at 14:01
  • I tried your script, and the log file is capturing the error code. Here is the grab from the log file: `ERROR: ORA-01017: invalid username/password; logon denied SP2-0734: unknown command beginning "DBMS_OUTPU..." - rest of line ignored.` – Incognito Feb 12 '13 at 09:55
  • May I know, what're you getting in log file when you execute the script? – Incognito Feb 12 '13 at 11:18

5 Answers5

19

What Max says is correct. Try this modified script

#!/bin/sh

echo "Please enter evaluate database username"
read eval_user
echo "Please enter evaluate database password"
read eval_pass
echo "Please enter the database name"
read db_name

LOGFILE=shell_log.txt

sqlplus -s /nolog <<-EOF>> ${LOGFILE}
WHENEVER OSERROR EXIT 9;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
connect $eval_user/$eval_pass@$db_name
DBMS_OUTPUT.put_line('Connected to db');
EOF

sql_return_code=$?

if [ $sql_return_code != 0 ]
then
echo "The upgrade script failed. Please refer to the log results.txt for more information"
echo "Error code $sql_return_code"
exit 0;
fi

Please note the use of sql_return_code to capture the SQLPLUS return code.

The DBMS_OUTPUT statement should fail with error - "SP2-0734: unknown command beginning...". You can find the error message in log file.

It is possible to trap the sp2 errors in SQLPLUS 11g using the error logging facility. Please have a look at http://tkyte.blogspot.co.uk/2010/04/new-thing-about-sqlplus.html for more information.

Aji Mathew
  • 396
  • 1
  • 7
  • I only get error code 122, instead of the actual db error message. Do you know of a way to capture the output? – roymustang86 Feb 12 '13 at 18:57
  • The error message is redirected to "shell_log.txt". Have a look at that file in your current directory. If you want to capture the output in shell script, you need to remove the redirection and assign the output of SQLPLUS to a variable. Eg:- `SQL_RESULT=$(sqlplus -s /nolog << EOF WHENEVER SQLERROR EXIT FAILURE WHENEVER OSERROR EXIT FAILURE SET SERVEROUTPUT ON connect $eval_user/$eval_pass@$db_name exec DBMS_OUTPUT.put_line('Connected to db'); exit EOF )` – Aji Mathew Feb 13 '13 at 07:05
  • 4
    Shell script in an UNIX OS can return codes up to 255. So I don't understand how WHENEVER SQLERROR EXIT SQL.SQLCODE; can properly return SQL codes above 255? E.g. ORA-12703 this character set conversion is not supported Actually I just did a test and ran a bad SQL that fails with ORA-00936: missing expression bad sqlplus returned 168 (!) So the actual return code 936 was wrapped at and just remainder got returned. 936%256=168. This is not a correct answer. – Tagar Aug 07 '14 at 22:56
7

it might be possible that your whenever statements are executed after connection to the db has been established (since you have mentioned them afterwards). Try the following code :-

$ORACLE_HOME/bin/sqlplus -s /nolog <<-EOF>> ${LOGFILE}
WHENEVER OSERROR EXIT 9;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
connect $eval_user/$eval_pass@$db_name
DBMS_OUTPUT.put_line('Connected to db');
EOF
Jason
  • 11,709
  • 9
  • 66
  • 82
Max
  • 4,067
  • 1
  • 18
  • 29
7

Aji's answer with

WHENEVER SQLERROR EXIT SQL.SQLCODE;

and then using

sql_return_code=$?

is not correct (or not correct in most cases). See details below.


Shell script in an UNIX OS can return codes up to 255. E.g. "ORA-12703 this character set conversion is not supported" return code should be 12703, but it doesn't fit into UNIX 8-bit return code.
Actually I just did a test and ran a bad SQL that fails with "ORA-00936: missing expression" -
sqlplus returned 168 (!).
So the actual return code 936 was wrapped at 256 and just remainder got returned. 936%256=168.


On Windows this probably could work (not tested), but not on UNIX (tested as explained above).


The only reliable mechanism is probably to spool results into a log file and then do something like

tail -n 25 spool.log | egrep "ORA-" | tail -n 1 | cut -d: -f1 | cut -d- -f2

So it would grep the spool log file and then cut actual latest ORA-code.

Tagar
  • 13,911
  • 6
  • 95
  • 110
  • 1
    The OP could just use `WHENEVER SQLERROR EXIT 10;` or something. But good point. It's possible the `SQLCODE` will mod 256 equal zero! – Jason Sep 16 '21 at 15:15
1

The fact you are entering fake values, are probably only related to the login. Then: Check database connectivity using Shell script

The WHENEVER ... are for errors during the SQL script execution. Once you'll successfuly connect with your script (I assume this your problem right now), you should get the kind of error managed by WHENEVER ERROR because you forgot the EXEC at your line with DBMS_OUTPUT.

Community
  • 1
  • 1
Plouf
  • 627
  • 3
  • 7
0

You can only trap sql error or os error. The dbms_output will fail at sqlplus level itself so the whenever error setting does not affect it.

rajesh
  • 21
  • 1