execute PL SQL Procedure from Shell Script - bash

Hi I'm trying to execute PL SQL Procedure from my Shell Script and get the return value (out value), but it's not working. Can anyone advise what I'm doing wrong? Here's what I have:
output="$(sqlplus -S user/pw#//ip:1521/db <<ENDOFSQL
set serveroutput on;
DECLARE
v_return PLS_INTEGER;
BEGIN
PKG.Procedure(v_return);
DBMS_OUTPUT.PUT_LINE(v_return);
END;
exit;
ENDOFSQL)"
echo $output

After a long day of trial and error I finally got it working with the below script:
#!/bin/ksh
CODE=`sqlplus -S $SCHEMA/$PW#//$IP_PORT/$DB << EOM
Set timing on
Set serveroutput on
Whenever sqlerror exit failure;
Whenever oserror exit failure;
declare
v_return number;
begin
PKG.Procedure(v_return);
end;
/
EOM`
if [ $? != 0 ]
then
echo "process failed."
exit 1
fi
exit $?

Related

Shell Script to trigger procedure with logging

Here is the shell script which need to trigger a stored procedure and when the record count is 0 then it should capture in the log that 0 duplicate records are found and if it's more than 0 then log with no of records.
Also if there is any sqlerror then it should write the same in the log file and it should send the communication in all scenarios.
We have funct file which has declared with all directories and we are referring here for the log file path directory.
Could you please help me to correct the code logic?
#!/bin/ksh
. /local/dir1/funct.sh
sqlplus -s ${ORAUSER}/${ORAPASSWD}#${ORASRVC} <<EOF > $LOG_TEXT
set head off
set serveroutput on
SELECT TO_CHAR(SYSDATE,'MMDDRRRRHH24MISS') FROM DUAL;
EOF
TIME_STAMP=`cat ${LOG_TEXT}`
LOG_FILE_NAME='FileStatus'${TIME_STAMP}'.log'
LOG_FILE=${LOGFILEDIR}'/FileStatus/'${LOG_FILE_NAME}
write_log "Database Timestamp is $TIME_STAMP"
write_log "Executing FileStatus now..."
sqlplus -s ${ORAUSER}/${ORAPASSWD}#${ORASRVC} <<EOF >> ${LOG_TEXT}
set feedback off
set heading off
DECLARE
v_count NUMBER;
BEGIN
select count(*) INTO v_count from (select col1,col2,count(col3) from Tab1 group by col1,col2 having count(col3)>1);
whenever sqlerror exit -1
whenever oserror exit -1
execute FileStatus;
END;
EOF
if [[ v_count -eq 0 ]] then
write_log "FileStatus executed successfully."
write_log "No Duplicate records Found: $LOG_FILE"
mailx -s "No Duplicate records Found" XXXXX#gmail.com < ${success}
elif [[ "$v_count -gt 0 ]]
then
write_log "FileStatus executed successfully."
write_log "Number of duplicate records found::$v_count:$LOG_FILE"
mailx -s "Number of duplicate records found:$v_count" XXXXX#gmail.com < ${success}
else
Write_log "FileStatus Failure."
mailx -s "FileStatus" XXXXX#gmail.com < ${failure}
fi
cleanup
exit 0;

Using spool in shell script but does not output file

I have a stored procedure in SQL written and I am trying to write the info from that procedure to an output file using shell script. I use spool, but I do not see the output file after the script was run.
My script:
run_procedure(){
userId="abc"
psswd="abcd"
package="Retrieve_data"
procedure="RETRIEVE_SERVER_DATA"
echo ${package}.${procedure}
sqlplus ${userId}/${passwd} >dev/null 2>&1 <<EOF
set serveroutput on;
set line 7000;
set feedback off;
set termout off;
spool /tmp/test.txt;
EXECUTE ${package}.${procedure};
spool off;
exit;
EOF
)
Here is where I call the above function:
if [[ $RETURN -eq 0 ]]; then
run_procedure
fi
(My return is equal to 0, by the way.)

How to add if-else condition in BEGIN END statement of the input Query to SQL PLUS

I have script to load tables from flat text file, so before loading the table I want to truncate the existing tables based on input files availability.
If input file is there truncate the table and load new data from file to table.
So while truncating I want to check if input file is present, so I wrote the code like:
truncateTables()
{
QUERY_TO_TRUNCATE_TABLES="ALTER SESSION ENABLE PARALLEL DML;
whenever sqlerror exit sql.sqlcode;
BEGIN
if [$IsFile1 == 'TRUE']
then
EXECUTE IMMEDIATE 'DELETE /*+ parallel(A,8) */ FROM TableName1 A';
else
echo "no input file"
fi;
if [$IsFile2 == "TRUE"]
then
EXECUTE IMMEDIATE 'DELETE /*+ parallel(B,8) */ FROM TableName2 B';
else
echo "No input file"
fi;
COMMIT;
END;
/
";
EXECUTE_TO_TRUNCATE_TABLES=`sqlplus -s $DB_CONN_STR << EOF
SET serverout on feed off heading off tab off serverout on pagesize 0 trimspool on linesize 1000
whenever sqlerror exit sql.sqlcode;
${QUERY_TO_TRUNCATE_TABLES};
EXIT;
EOF`
retVal=$?
errorORA=`echo "${EXECUTE_TO_TRUNCATE_TABLES}" | grep -i 'ORA' | wc -l`
errorSP=`echo "${EXECUTE_TO_TRUNCATE_TABLES}" | grep -i 'SP' | wc -l`
if [[ $retVal -ne 0 || ${errorORA} -ge 1 || ${errorSP} -ge 1 ]]
then
echo "Exiting with failure.......\n$retVal\n........"
echo "Delete tables FAIL."
else
echo "tables Delete is Successful"
fi
}
But it seems we can not use if else condition in between BEGIN and end? how we can modify this code so that I can pass it to SQL PLUS? any other way also okay for me.
Actually you mixed PLSQL code and ksh.
It is possible to build your query with conditions from your kornshell. Here is how it would start:
truncateTables()
{
QUERY_TO_TRUNCATE_TABLES="ALTER SESSION ENABLE PARALLEL DML;
whenever sqlerror exit sql.sqlcode;
BEGIN
";
if [ "$IsFile1" == "TRUE" ]
then
QUERY_TO_TRUNCATE_TABLES=${QUERY_TO_TRUNCATE_TABLES}"
EXECUTE IMMEDIATE 'DELETE /*+ parallel(A,8) */ FROM TableName1 A';
;"
else
echo "no input file 1"
fi
if [ "$IsFile2" == "TRUE" ]
then
QUERY_TO_TRUNCATE_TABLES=${QUERY_TO_TRUNCATE_TABLES}"
EXECUTE IMMEDIATE 'DELETE /*+ parallel(B,8) */ FROM TableName2 B';
";
else
echo "No input file 2"
fi
QUERY_TO_TRUNCATE_TABLES=${QUERY_TO_TRUNCATE_TABLES}"
COMMIT;
END;
/
";
Hope this helps

Trap ORA errors in unix(HP-UX) shell script

Script:
while read -r records
do
sErrors=`sqlplus /<<EOF
WHENEVER SQLERROR EXIT SQL.SQLCODE;
select id from table where name='"$records"';
#if select succeeds then update
update table set name='xyz';
exit;
EOF`
if [[ $sErrors = "ORAsomenumber" ]]
then
echo "Failed for $records with error:$sErrors">>logfile.log
fi
done<file
I need to trap any error specific to select query(i.e. "NO DATA FOUND") or any
Database specific error that might occur for a record in a while loop and continue
without exit till the end of reading all records
Oracle version : 10.2.0.5.0
Note: it is not mandatory to get specific ORA error only, any hint indicating the specific db error would be enough
Thanks.
file:
name1 newname1
name2 newname2
name3 newname3
script:
#!/bin/sh
#set var
export ORACLE_HOME=/oracle/product/db_1/
export ORACLE_SID=orcl
export PATH=$ORACLE_HOME/bin:$PATH
ora_user="user"
ora_pwd="password"
ora_tns="dbtnsname"
log_file=/var/log/sql.log
while read user newname
do
sqlplus -S $ora_user/$ora_pwd#$ora_tns <<EOF >>$log_file
SET SERVEROUTPUT ON
DECLARE V_ID INT DEFAULT 0;
BEGIN
SELECT ID INTO V_ID FROM TABLE WHERE NAME = "$user";
IF V_ID = 0 OR V_ID IS NULL
THEN
DBMS_OUTPUT.PUT_LINE("FAILED FOR $user WITH ERROR:NOT DATA FOUND");
ELSE
UPDATE TABLE SET NAME="$newname" WHERE NAME = "$user";
COMMIT;
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE("FAILED FOR $USER WITH ERROR:"||SQLERRM);
END;
/
EOF #must top grid
done<file
The way the sqlplus invoked is fine in your script, But string comparison does not work as it contains the whole error if you want to check for some particular error code (or) only some part of the string, Use grep command.
echo $sErrors | grep "ORA-ERROR1" && echo "ORA-ERROR1 Found"
echo $sErrors | grep "ORA-ERROR2" && echo "ORA-ERROR2 Found"
In the above case, it prints both grep output and the echo command output if it matches.
If you don't want the output to be printed, You can follow the below.
echo $sErrors | grep "ORA-ERROR1" > /dev/null 2>&1
if [ $? -eq 0 ];then
echo "ORA-ERROR1 Found"
fi

Issue with execution of PLSQL block in Shell script

I am trying to drop tables, which have a particular suffix(passed as argument $1), using shell script.
If a parent table is selected without its child tables being dropped, I am bypassing the parent table and increasing the counter in the exception block.
When I run this script in sql developer with $1 replaced with the proper value, it works. But when I run this shell script, it is getting stuck.
Could you please have a look and let me know, what am I missing in the shell script?
Code:
#!/bin/bash
cat <<ENDDROPNEWTABS >dropnewtabs.sql
set pagesize 100
DECLARE
t_cnt NUMBER;
CURSOR C001
IS
SELECT table_name FROM user_tables WHERE table_name LIKE '%$1%';
BEGIN
BEGIN SELECT COUNT(*) INTO t_cnt FROM user_tables WHERE table_name LIKE '%$1%';
END;
WHILE(t_cnt > 0) LOOP
FOR i IN C001 LOOP
BEGIN EXECUTE IMMEDIATE 'DROP TABLE '||i.table_name;
EXCEPTION
WHEN OTHERS THEN
t_cnt := t_cnt+1;
NULL;
END;
t_cnt := t_cnt-1;
END LOOP;
END LOOP;
END;
exit
ENDDROPNEWTABS
echo "Dropping the tables created for this task..."
sqlplus -s usn/pwd#sid #dropnewtabs.sql >tablesDropped.txt
#END
You are missing a / after the END; of your anonymous block, so it will never execute it, and the exit will be seen as part of the previous command. The / is very roughly analogous to 'run' in SQL Developer.
...
END LOOP;
END;
/
exit
ENDDROPNEWTABS
(You don't need the BEGIN/END around the SELECT, or the NULL in the exception handler, but those won't break anything; it's also not a good idea to squash all possible exceptions silently, just look for the one you're expecting to see. And personally I find it easier to follow with some indentation).
#!/bin/ksh
PSQL1=dropnewtabs.sql
TABNAME=$1
echo $1
>tablesDropped.txt
>$PSQL1 #this command will create a new empty file
echo "set echo off feed off head off pages 0 " >> $PSQL1
echo "set serveroutput on " >> $PSQL1
echo "set define off " >> $PSQL1
echo "DECLARE " >> $PSQL1
echo "CURSOR C001 " >> $PSQL1
echo "IS " >> $PSQL1
echo "SELECT table_name FROM user_tables WHERE table_name = '$TABNAME'; " >> $PSQL1
echo "BEGIN " >> $PSQL1
echo "FOR i IN C001 " >> $PSQL1
echo "LOOP " >> $PSQL1
echo "EXECUTE IMMEDIATE 'DROP TABLE '|| i.table_name ; " >> $PSQL1
echo "dbms_output.put_line('TEST-------->'); " >> $PSQL1
echo "END LOOP; " >> $PSQL1
echo "END; " >> $PSQL1
echo "/ " >> $PSQL1
echo "exit;" >> $PSQL1
echo "Dropping the tables created for this task..."
sqlplus -s user/pwd#sid #$PSQL1 >>tablesDropped.txt 2>&1
echo "Complete"

Resources