#!/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?
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'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.
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
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.
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.
Related
Trying to connect to ORACLE SQLPLUS using unix shell script. But it is getting failed..
Looks like the script in line 3 is incorrect as I am passing username, password and SID
#!/bin/sh
cd /dev/shrd/alt/test1/stest/ptest
V1=`sqlplus testuser/passwd#testSID <<EOF
SELECT count(*) FROM test_table WHERE region='Aus';
EXIT;
EOF`
if [ -z "$V1" ]; then
echo "No rows returned"
exit 0
else
echo $V1
fi
I got an error stating -ORA-12162: TNS:net service name is incorrectly specified when I added - sqlplus $username/$password in the script.
Can anyone please confirm if the below syntax is valid and I can add it in shell script?
> sqlplus MyUsername/MyPassword#MyHostname:1521/MyServiceName
Kindly guide me if I'm missing something (like Hostname, Port Number,TNS_entry or something else).
Thanks in advance :)
Until you are successful in obtaining any output from your sqlplus command, you should not use "-S". Without that, sqlplus will provide you with much-needed error-reporting/feedback to debug your command interface/call.
Also, as per this, it is inadvisable to provide the password on that command line. For that reason, the service/DB administrators probably disallow that form of accessing the service/DB/
I have a Oracle JOB that runs a executable (bash script)..
This scripts runs itself SQLPLUS which runs a PACKAGE
Check this
function run_pkg_load_svr() {
if [ "$1" != "" ] && [ "$2" != "" ];
then
sqlplus -l -s $1/$2 <<EOF
WHENEVER SQLERROR EXIT 99;
WHENEVER OSERROR EXIT 88;
BEGIN
PKG_LOAD_SVR.SP_MAIN();
END;
/
EOF
pkg_retcode=$?
echo $DATE_LOG >> upload.log
echo "PKG EXIT CODE: " $pkg_retcode >> upload.log
fi
}
SO, if I run the JOB, its exit code (PKG) is 1
But, If I run manually the package or the script, it works
STATUS is SUCCEEDED in log events
How is possibile to have such a problem?
In addition, when SP_MAIN starts I populate also a log_table..
even that doesn't work
You probably doesn't even connect to the database.
I get the same 1 status here if I give wrong user /password:
host:/jcho $ sqlplus -l -s a/b#database <<EOF
> select 1 from dual;
> EOF
ERROR:
ORA-01017: invalid username/password; logon denied
SP2-0751: Unable to connect to Oracle. Exiting SQL*Plus
host:/jcho $ echo $?
1
... First be sure you are able to connect.
edit
I also get same error when database I try to connect doesn't exist:
host:/jcho $ sqlplus -l -s a/b#unknown_database <<EOF
> select 1 from dual;
> EOF
ERROR:
ORA-12154: TNS:could not resolve the connect identifier specified
SP2-0751: Unable to connect to Oracle. Exiting SQL*Plus
host:/jcho $ echo $?
1
So make sure you're in the same context when commands are run from Oracle Job and manually. Especially, display content of environment variables ORACLE_SID, (TWO_TASK?), ORACLE_HOME and PATH (PATH should contain $ORACLE_HOME/bin);
And also check variables are correctly set by displaying them from your script: add
echo USER-PASSWORD: $1-$2
as first line of your function.
I am new to shell script .
i am writing a code for DBA automation in which i have master.sql file have declarations of n number of sqls . and these sqls are placed inside particular folder .
i have a script which is calling this master.sql and executing those sqls at once indirectly and saving in the log file
sqlplus command is saving the output of all the sqls declared inside master.sql at once
wwhat i want is it must stop the execution when the first sql fails and return the error witht the specific sql which failed or ask to rollback and asking do you want to continue or not ?
tried using sqlplus whenever,, sqlerror ,$? nothing worked
sqlplus ${USER}/${PASS}#$SID #master.sql > /home/deploy/vidya/properties/result/result.log
Now what i am trying to do is .... i want to stop the execution of sqls when any of the sql fails from the starting and prompts on the command line with the error and specify which sql fails
master.sql
SET ECHO ON
#/home/deploy/vidya/properties/001_dba_demo.sql
#/home/deploy/vidya/properties/003_dba_demo1.sql
#/home/deploy/vidya/properties/002_dba_demo2.sql
#/home/deploy/vidya/properties/004_dba_demo2.sql
EXIT
my .sh script which is calling master.sql and its working properly
#!/bin/bash
echo "Enter schema Name you want to connect: "
read USER
echo "Enter password: "
read -s PASS
#echo "Enter Oracle SID for the environment you want to connect with : "
#read SID
echo "Enter Environment for the environment you want to connect with : "
read ENV
echo "Enter Oracle SID for the environment you want to connect with : "
read SID
export ORACLE_SID=${SID}
if [ $ENV == UAT ]
then
echo "Connected withh UAT ORACLE HOME:"
export ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1
elif [ $ENV == PROD ]
then
echo "Connected with PROD ORACLE HOME:"
export ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1
else
echo "Wrong Environment Entered :"
fi
export PATH=$ORACLE_HOME/bin:$PATH
echo "want to execute sql? y/n"
read yn
sqlplus ${USER}/${PASS}#$SID #master.sql > /home/deploy/vidya/properties/result/result.log
**
can anyone help?**
One ideea would be to launch the sql's in sequence and check them afterwards for errors:
e.g.
sqlplus ${USER}/${PASS}#$SID #dba_demo.sql > /home/deploy/vidya/properties/result/result_dba_demoSQL.log
checker = $(grep "ERROR" result_dba_demoSQL.log)
if [ test -z $checker ]
then echo "dba_demo_SQL successfull run"
else
echo "dba_demo_SQL failed"
exit 0
fi
The exit 0 part, exits the whole script when grep find an error in the log file.
i guess sqlplus has the main feature to execute the sqls at once and saving it in log file . it is doing it already . what i want is to execute every sql one by one and if any sql fails then it should stop the execution and give the error on command line
Sorry for not using comments. Don't have enough reputation.
That's my solution in the first answer.
Instead of launching the master.sql via sqlplus, launch the smaller sqls one by one and check the log file after each execution.
If the log file for sql number 1 has errors, the exit 1 in the if clause will terminated the whole script.
#First query
#Sqlplus command to run the first query
sqlplus ${USER}/${PASS}#$SID #dba_demo.sql > /home/deploy/vidya/properties/result/result_dba_demoSQL.log
#variable checker is assigned ERROR, if ERROR is found in file (you have to check what errors you can get from oracle)
checker = $(grep "ERROR" result_dba_demoSQL.log)
#If clause that checks if variable checker is empty or not, if variable checker is empty, it means that no string "ERROR" was found in log files, thus script continues to run; If variable is not empty (string ERROR was chatched) script terminates.
if [ test -z $checker ]
then echo "dba_demo_SQL successfull run"
else
echo "dba_demo_SQL failed"
exit 1
fi
# Second Query
sqlplus ${USER}/${PASS}#$SID #dba_demo1.sql > /home/deploy/vidya/properties/result/result_dba_demo1SQL.log
checker = $(grep "ERROR" result_dba_demo1SQL.log)
if [ test -z $checker ]
then echo "dba_demo1_SQL successfull run"
else
echo "dba_demo1_SQL failed"
exit 1
fi
If your master.sql is the same as the example you posted, meaning a list of paths to sql files themselves, you can do this:
# Read the master.sql file, for every line in master.sql file
for i in `cat master.sql`; do
# basename "$i" takes the name of the file from path present in master.sql
sql_name = $(basename "$i")
# use path in the sqlplus command ($i from the for loop) and sqlname for the log file name
sqlplus ${USER}/${PASS}#$SID #$i > /home/deploy/vidya/properties/result/result_$sql_name.log
checker = $(grep "ERROR" result_$sql_name.log)
if [ test -z $checker ]
then echo "$sql_name successfull run"
else
echo "$sql_name failed"
exit 1
fi ; done
I am trying to understand a simple script that connects to Oracle database using sqlplus command in unix:
1 sqlplus -s /nolog > /dev/null 2>&1 <<EOF
2 whenever sqlerror exit failure
3 connect $user_pwd
4 exit success
5 EOF
If I am using unix then I use commands as sqlplus $user_pwd for connecting to oracle database and to come out of sqlplus command I use exit. Please help me in understanding the lines 1,2,4,5. It may be a simple question for experts but I am not able to understand when to use these.
-s is for silent mode (not output anything)
> /dev/null 2>&1 things are for force to not display anything. (redirect standard output and standard error to /dev/null)
/nolog is for not trying to login with the command line arguments. (the login credentials aren't provided here.)
<<EOF is a heredoc input redirect. The lines until EOF will be passed to sqlplus as standard input. (So this is why the last line is EOF)
About the whenever line: http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12052.htm So the command's return value will be failure if something wrong happens.
connect $user_pwd connects the sqlplus to the server
The exit success makes sqlplus returning will success. http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12023.htm#i2697968
I have a ksh shell script that runs a .sql script with a background and wait statement. Is it possible for me to capture the generic "ORA-0" error and exit out completely?
So far:
$ORACLE_BASE/bin/sqlplus 2.sql &
pid2=$!
echo "Waiting for PID:$pid2"
wait $pid2
#look for error here
#exit program if oracle error
SQL*Plus is kind of a shell itself, so it catches the errors from oracle and continues execution. You want to look at the SQL*Plus command WHENEVER SQLERROR, especially WHENEVER SQLERROR EXIT that allows to exit immediately with an error code.
So, at the beginning of your .sql script you add something like :
WHENEVER SQLERROR EXIT SQL.SQLCODE
And if there is an SQL error it will exit with the relevant error code.
Now, in the shell script after the wait you can get the error by reading $?.
Something like (depending on the exact syntax of your shell) :
wait $pid2
ret=$?
if [ $ret != 0 ] # if not success
then
exit $ret # propagate error code
fi