SQLPlus Connection Issue when using bash script - bash

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/

Related

Using SQLPLUS command in UNIX scripts

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

Execute SQL query on Oracle working in Unix prompt but not in shell script

I am trying to connect to an Oracle db using a ksh script. When I run this directly from the prompt, it works. But when I put it inside a script (abc.sh) it fails. Below is what I've put in the script (edited to make it shorter):
Here abc is the username, while abc$123 is the password of the user which has access on database DBNAME.
#!/usr/bin/ksh
sqlplus -s /nolog << EOF > output
connect abc/abc$123#DBNAME;
set echo off
set heading off
select table_name from dba_tables;
exit;
EOF
This works if typed directly, but run as ./abc.sh, gives error -
ERROR ORA-01017: invalid username/password; logon denied
I'm sure I'm missing something simple, but can't figure this out. Thanks for your help.
You cannot just write code like this and expect it to be passed to the relevant program. Your SQL lines are being executed by KSH instead of your SQL server. Instead you need to do something more along the lines of:
echo "SQL CODE HERE" | sqlplus ....

Managing error handling while running sqlplus from shell scripts

#!/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.

Running pl/sql in Korn Shell(AIX)

I have a file to execute in Ksh written by someone. It has a set of commands to execute in sqlplus.
It starts with,
sqlplus -s $UP <<- END
followed by a set of ddl commands such as create,drop,etc.,
When I execute the file in the shell, I get the error in the starting line quoted above.
I understand "-s" starts the sqlplus in silent mode and $UP is the connection string with username/password. But I couldn't make heads or tails of "<<- END" part(Many sites from google says input redirection is "<<" not "<<-"). So I presumed the error must be in that part and removed it from the file.
Now it reads,
sqlplus -s $UP
But once I execute the file, It waits for input from the shell, instead of reading the rest of the lines from the file. How would I make sqlplus to execute the ddl commands in the rest of the file?. Thanks in advance.
Here "END" is a block marker and "-" is not required.
For running sqls from a shell script , One simple example is given below.
sqlplus system/manager << ENDOFSQL
whenever sqlerror exit sql.sqlcode;
select sysdate from dual;
exit;
ENDOFSQL
Thanks,
Rinson KE
DBA

SQL select statement in UNIX inside/within IF..THEN statement

I just want ask the steps when trying to create a simple SQL select statement in UNIX inside/within IF..THEN..FI statement.
I know how to use the 'select' and 'if..then' statements in SQL*Plus, but I'm having a difficulties having a UNIX script to point to variables: If 'ABC' to 'Select...'
Example:
if [ "$?" = 'ABC' ]
then
SELECT employid, name, age FROM tablename;
else
exit 1
fi
if [ "$?" = 'XYZ' ]
then
SELECT employid, name, age FROM tablename;
else
exit 1
fi
How do I put it in a UNIX script more correctly syntax wise and right to the point?
Thanks.
This sounds like you're trying to embed SQLPlus in a shell script. From memory the incantation should look something like:
if [ $? -eq ABC ]; then
SQLPLUS /S USER/PASS#Instance <<EOF
SET echo off;
SET pagesize 0;
SET heading off;
SPOOL foo.out
select foo from bar
EOF
fi
Everything between the SQLPLUS and EOF is passed to SQLPlus, so we have some statements to control the formatting (you may want different ones) and the actual query. The SPOOL command in the SQLPlus script sends the output to a file. For more detailed docs on using SQLPlus, You can download them from Oracle's web site.
Remember that echo is your friend.
if [ "$?" = "ABC" ] then echo SELECT employid, name, age FROM tablename; else exit 1; fi
You can embed shell script variables and such. Be careful of the need to quote things the shell wants to act upon, like quotes and semi-colons.
Have you considered using perl or other scripting language that includes database connection functionality. That way you avoid the clunky shell script/SQL*Plus linkage
The above answer was ok. However, I knew that, using SQLPlus in a shell script and unfortunately, I don't need the SQLPlus script to send the output to a file. In other words: Is there any other way of doing this, just print the output to a log?

Resources