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

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?

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/

Run sqlplus commands from multiple files with query logging or spool in Windows Batch File

I am quite new to batch scripting, and I am trying to run multiple sql files, which in turn may contain multiple sql DML/DDL queries from bat file. The output files must contain all the queries being executed and the query output. Unlike this example , I don't have spool command inside my sql file, and I can not edit the input sql files. The following command works for me in ksh file (thanks to here-document):
$sqlplus /nolog <<! >>$sqlLogs.lst
connect $USERNAME/$PASSWORD#${DBNAME}
set echo on timing on
spool ${SCRIPTRUNFILE_SPOOL}
select name from v\$database;
#${SCRIPTRUNFILE};
spool off
exit
!
I want the exact same in Windows bat file. I have tried using ^. I can't do combine all sql files into one, as I need logging for each sql file into different file. My attempt at the bat file script is as follows and I have played around this much, and it fails with spool command not recognized. I also prefixed below commands with sqlplus, but still unable to achieve something like above ksh file:
sqlplus -s username/pwd#DBName >> sqlLogs.lst
set echo on timing on
spool %RUNFILENAME%.lst
#%RUNFILENAME% > %RUNFILENAME%.lst
select name from v\$database;
spool off
quit
Following logic executes my scripts but does not log the query being executed. Also, I don't want to connect twice to the database.
echo select name from v$database; | sqlplus -s username/pwd#DBName >> sqlLogs.lst
echo quit | sqlplus -s username/pwd#DBName #%SCRIPTRUNFILE%>> %SCRIPTRUNFILE_SPOOL%.lst
Can someone here please help to spool to a file where I can log the queries as well, while maintaining a single DB Connection?
Pass your immediate SQL*Plus commands to your sqlplus via stdout, grouped together by Windows' ( and ) symbols...
(
echo.set echo on timing on
echo.spool %SCRIPTRUNFILE_SPOOL%
echo.select name from v$database;
echo.#%SCRIPTRUNFILE%
echo.spool off
echo.exit
) | sqlplus -s %USERNAME%/%PASSWORD%#%DBNAME% >> sqlLogs.lst

Why does this sqlplus connection string is not working in 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.

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.

pass sqlplus value to shell variable

the below picture shows what gets returned when I run sqlplus in shell
but when I run this from the "run" command:
powershell.exe -noexit c:\sqltriggers\voicetrigger2.ps1
with voicetrigger2.ps1 as this:
$(sqlplus user/pass#OMP1 '#C:\sqltriggers\VOICEBLOCKTRIG.SQL');
I get this:
I should expect a 3 back. The issue is, I try to set that as a variable, and if the integer is greater than zero, run a BAT file. But I don't think the SQLPlus is returning JUST an integer value. I think its actually returning this:
count(*)
3
How do I get it to just return the integer value from the SQLplus command?
SQL*Plus isn't returning anything, it's displaying the result of the query on standard output. To get the direct call to only show 3 you can set heading off in the SQL script, and also call SQL*Plus with the -s flag to suppress the banner. You probably also want an exit at the end of the SQL script so it doesn't stay sitting at the SQL> prompt.
The same applies to the powershell call, but there's something else going on there; the 17 is a line number which means it's waiting for more input and hasn't executed the commands in the SQL script, which suggests either a query without a terminating ; or /, or a PL/SQL block without a terminating /. But if it's exactly the same SQL you ran in the first example then that is a bit odd as they should behave the same. You should add the SQL script contents to the question to see what might be wrong.
The only thing I can think of that would change behaviour like that is if you had a login.sql that includes a set sqlterminator command, but you'd have to be picking up different login.sql files from the two calls... which is plausible if powershell has its own environment variables, perhaps.
It won't work this way. As Alex mentioned, sqlplus doesn't return anything as a function - it only writes whatever output you generate to standard output.
You can have variables in sqlplus, but there is no easy way to pass them to host environment. The only way I can think of is to use spool command to generate another batch file, which will actually set your host variables, and then process them the way you want in your host script.
Something like this:
16:30:20 SYSTEM#sandbox> get host.sql
1 SET VERIFY OFF TRIMSPOOL ON TERMOUT OFF HEADING OFF LINESIZE 4000 PAGES 0 FEEDBACK OFF timing off
2 spool s:\.tmp\host.ps1
3 select '$env:MY_VAR="'||dummy||'"' from dual;
4 spool off
5* exit
16:30:25 SYSTEM#sandbox> #host.sql
Disconnected from Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production
PS S:\.tmp> cat host.ps1
$env:MY_VAR="X"
PS S:\.tmp> .\host.ps1
PS S:\.tmp> $env:my_var
X
PS S:\.tmp>
sqlplus -s /nolog <<EOF > query_result.txt
set heading off feedback off pagesize 0 linesize 30000 trimout on ;
select 5 from dual;
exit;
EOF
for i in `cat query_result.txt `
do
exit $i
done
try adding SET HEADING OFF in the beginning of your file. Check this answer (check the second best voted answer)

Resources