Why does this sqlplus connection string is not working in bash? - bash

I am trying to connect to oracle db hosted on a server here is my script
#!/bin/bash
RAW=`cat sqlTemp.sql`
IFS=";"
exit=" exit;"
for var in $RAW
do
query=$(echo $var | sed '/^$/d')
sqlplus64 username/pwd#hostname:portnumber/servicename $query 2>> errorLog.txt
ERRORCODE=$?
if [ $ERRORCODE != 0 ]
then
echo "$ERRORCODE" >> "errorLog.txt"
echo "this query has error- check the log file for detail"
else
echo "SUCCESS"
fi
done
If i replace connection string by
sqlplus64 -S username/pwd#hostname:portnumber/servicename <<ENDOFSQL
whenever sqlerror exit sql.sqlcode;
$query
exit;
ENDOFSQL
the script work.
what is wrong with the previous connection string and how to correct it ?

There is no difference in the connection string, "username/pwd#hostname:portnumber/servicename", in your two commands. The difference is in how you try to present the SQL commands you want to have executed. There are at least two important differences between the command that fails and the one that works.
The one that works uses a here document to redirect several lines of input, including your "query" string, into the command's standard input, whereas the one that fails expands the query string among the command line arguments, which is a completely different thing.
When the query string is presented unquoted on the command line it is subject to word splitting after it is expanded, but the same does not apply when it appears in a here document
Most likely, the sqlplus64 command expects its SQL input to be presented on the standard input, which you already know how to do. If it were prepared to accept SQL on the command line, then at minimum it would need to be quoted, and there would probably be a command-line option to tell it to look there for the SQL.

Related

SQLPlus Connection Issue when using bash script

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/

Bash control flow using || on function, with set -e

If I put set -e in a Bash script, the script will exit on future errors. I'm confused about how this works with functions. Consider the following, which will only print one to standard out:
set -e # Exit on error
fun(){
echo one
non_existing_command
echo two
}
fun
Clearly, the non_existing_command is an error and so the script exits before the second echo. Usually one can use the or operator || to run another command if and only if the first command fails. That is, I would suspect the following to print out both one and three, but not two:
set -e # Exit on error
fun(){
echo one
non_existing_command
echo two
}
fun || echo three
What I get however is one and two. That is, the || operator prevents the exit (as it should) but it chooses to continue with the function body and disregard the right-hand command.
Any explanation?
It appears to be documented in the set builtin command
If a compound command or shell function executes in a context where -e is being ignored [such as on the left-hand of a ||], none of the commands executed within the compound command or function body will be affected by the -e setting, even if -e is set and a command returns a failure status.
Emphasis and comment are mine.
Also, if you try to set -e within the function, don't bother: the next sentence:
If a compound command or shell function sets -e while executing in a context where -e is ignored, that setting will not have any effect until the compound command or the command containing the function call completes.

Capturing return codes from Sybase stored procedure in korn shell script

I am facing an issue in capturing the return code of a stored procedure.
I am calling a sybase stored procedure in my korn shell script using isql statement as mentioned below.
isql -U ${APPLID} -S{SERVER}> ${sqlMsg} << EOF
use ${DATABASE}
go
exec stored_procedure
go
EOF
returncode=$?
If an error occur inside the stored procedure, I am not able to capture if I follow the below method.
if [ $returncode -ne 0 ]
then
print "failed"
fi
I tried using a return statement inside the stored procedure like
return (1)
but this didn't give me expected results. When i echoed the returncode, it echoed as 0, even after returning the status as 1.
return status as 1 was seen in the sql logs.
To capture the error inside your sql statement, you will need to look at ##error
returncode=`isql -U ${APPLID} -S{SERVER}> ${sqlMsg} << EOF
use ${DATABASE}
go
exec stored_procedure
go
select ##error
go
EOF`
This should allow your if condition to work as you expect.
The $! variable returns execution status of the isql program, not the store procedure status.
That is the reason why the returncode being echoed prints 0: the isql program itself worked properly.
To catch the output from your store procedure, I would redirect it to an external output file and read it. The isql utility has several options for manipulating with input/output files,
such as -i input_file and -o output_file for specifying input and output files accordingly. If your store procedure has an output, it will be sent to the output_file.
Now you may read the output_file content from your script by a simple "cat" or more sophisticated loop, depending on the output_file content. To create an output file with a unique name use $$ variable which gives you current PID of the script. Delete the output file at the end.
#!/bin/bash
output_file=output.$$
isql with all your prameters and -o $output_file
status=`cat $output_file`
echo $status
rm $output_file

Write a report of what the shell would done

In my UNIX shell script I need to insert a parameter to start it. This parameter can assume two valors (test and production). Inside the code I make an insert in an Oracle db. After this insert I have to make a condition that if the parameter is test then write the spool in another file and don't connect the db, else connect the db and make the insert normally. Fundamentally there are two ways; in the test I just want to see what the shell is going to do and the production that it makes the normal insert and his operations. I try this after the insert but I get a error:
if [[ "$choice" = "test" ]];
then
${TMP_PART2DAT} > ${TMP_REPORT}
else
SP_SQLLOGIN="$ORACLE_DB_OWN/$ORACLE_PWD#$ORACLE_SID"
sqlplus -S -L ${SP_SQLLOGIN} #${TMP_PART2SQL}
fi
Any ideas?
Try running your shell script with "bash -x" mode. You would be able to trace the command execution.
Try
cat ${TMP_PART2DAT} > ${TMP_REPORT}
for line 3 of your script.
This will overwrite everything in TMP_REPORT with the contents of TMP_PART2DAT.

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