How to get output of sqlite command in shell script - shell

I am trying to make rollback if something went wrong during the execution of my sql crud operations or if it can not make commit with shell scripting.
I have test2.sh and test.sh
test.sh:
#!/bin/sh
sqlite3 dB.sqlite << EOF
begin;
select * from Table1;
and test2.sh
#!/bin/sh
if echo `./test.sh`|grep -q "SQL error"; then
rollback;
else
err=commit;
if echo $err |grep -q "error"; then
rollback;
fi
fi
There is no table called Table1 and i expected to get the sql error output of test.sh and rollback.
But it gives error : rollback: command not found.
How can i get the error and make rollback? or Is this way that i follow right?

Your test2.sh script fails because the shell is trying to execute a program called rollback, hence the "command not found". You want to use the sqlite instruction rollback, whichs means you'd have at least to do this :
sqlite3 dB.sqlite << EOF
rollback;
EOF
But I don't think this will work. As I see it, rollback has to occur within the same sqlite session as the one started by test.sh to have any effect. Your test.sh script already makes sqlite plow through the commands until it reaches EOF, when you grep the errors with test2.sh, it's already too late. There's no way you can do a rollback from the test2.sh script, which sits outside that sqlite session.
So, to complete my answer, I recommend you to step away from Bash scripting and use a programming language, which will allow you to open a sqlite session, execute commands and control the transactions. Quick example in Python :
import sqlite3
conn = sqlite3.connect('dB.sqlite')
c = conn.cursor()
try:
c.execute('INSERT INTO Table1 VALUES(1)')
conn.commit()
except:
conn.rollback()
c.close()

Related

sqlplus not properly ended script

i have a plsql script, which is not properly terminated:
create or replace package mypackage
... (no semicolon/forward slash at the end)
the script is executed with sqlplus (12.1) on windows powershell:
sqlplus user/pass#host #my_not_properly_ended_file.pks
i would expect sqlplus to terminate with exit code 1 and an error message, but instead it prompts for input.
how can i get an error message and exit code in this situation?
edit: solution should also work with dml statements that are not terminated with a semicolon.
You can use shell redirection instead of #:
sqlplus user/pass#host < my_not_properly_ended_file.pks
This will also prevent it getting 'stuck' if the script doesn't end with an exit command.
However, it won't return an error code to the shell in either case. As far as SQL*Plus is concerned you put the incomplete statement into its buffer but never attempted to execute it (as there was no slash); and as it didn't run, it didn't error. So setting whenever sqlerror or whatever won't make any difference either.

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.

Stop execution of PL/SQL when error without using raiserrror

See this code:
test.sh
#!/bin/bash
echo "hello!"
klsdslkdsd
echo "bye"
When I run it I get:
hello!
/tmp/test.sh: line 3: klsdslkdsd command not found
bye
Although there is a syntactic error, the execution goes one (is a script after all).
Now, if I do:
testWithStop.sh
#!/bin/bash
set -e
echo "hello!"
klsdslkdsd
echo "bye"
I get:
hello!
/tmp/test.sh: line 5: klsdslkdsd command not found
The execution stops because I get an exit error from every executed line. If exit != 0 it aborts.
I would like to replicate this behavior in a set of (oracle) PL/SQL (and solely SQL) code.
At this point, even with error, the Oracles DB Manager manages the error gracefully and don't stop the execution of the SQLs. I would like that, when an error (syntactic or semantic) is found, the program aborts but without touching the logic of the program (if so, I would have to change several hundreds of PL/SQL and is not possible).
I know I could do it using raiserror or creating a macro anonymous block that encapsulate portions of my codes, so I could retrieve the exceptions. As I said, it could not be possible to do with several hundreds (could be thousands) of isolated (and logic complex) PL/SQLs
Is there an equivalent to set -e in SQL or an elegant way to do it?
EDIT:
In particular, I´m executing (and calling) de PL/SQLs via a shell script (bash).
For example, the sqlbash.sh file:
#!/bin/bash
sqlplus ..... <<EOF
select * from table;
sdsdsfdsf <--- intentional error!
select * from table2;
EOF
If I called the script, I will get the syntactic error, but the execution goes on and doesn't abort. I would like to abort, for example, mimicking the behavior of an exit 1.
Something like:
#!/bin/bash
sqlplus ..... <<EOF
select * from table;
sdsdsfdsf <--- intentional error!
exit 1 <--- it will abort and the script WILL FAIL at this point
select * from table2;
EOF
I'm working with an scheduler, so, it is necessary for me to see that the script fails, not that it was executed and gave me warnings.
Your looking for WHENEVER SQLERROR and/or WHENEVER OSERROR SQL*Pus commands. They allow you to, among other things, exit if something bad happens in the middle of the script.
Put something like
whenever oserror exit 1
whenever sqlerror exit 2
at the top of your scripts, and you'll be able to tell from your shell script that something failed.

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

Resources