Pass shell variables to SQL statement - sql

I want to pass shell variables to sql statement. Both shell script and SQL statement are present in the same script file.
I want the values of the variables retMonth, retLastDay and retPrvYear in the SQL statement.
Below is the code.
If I execute this, it prints - " partition_date between '01--' and '--' \ 0 0] 1 1] 12-DEC-14 1"
How can I have values of retMonth, retLastDay and retPrvYear in SQL statement?
echo $retMonth //This prints 07
echo $retLastDay //This prints 31
echo $retPrvYear //This prints 2015
count=$(sqlplus -s ${DBA_ORACLE_USER}/${DBA_ORACLE_PWORD}#${ORACLE_SID} <<END
#connect ${DBA_ORACLE_USER}/${DBA_ORACLE_PWORD}#${ORACLE_SID}
set serveroutput on
set linesize 1000
set heading off
set feedback off
define lastMonth=$retMonth
define lastYear=$retPrvYear
define lastDay=$retLastDay
SELECT count(1)
FROM MYTABLE
WHERE partition_date between '01-$lastMonth-$lastYear' and '$lastDay-$lastMonth-$lastYear'
);
END
)

Try using quoted shell variables directly without using define directives:
count=$(sqlplus -s "${DBA_ORACLE_USER}/${DBA_ORACLE_PWORD}#${ORACLE_SID}" <<END
set serveroutput on
set linesize 1000
set heading off
set feedback off
SELECT count(1)
FROM MYTABLE
WHERE partition_date between
"01-$retMonth-$retPrvYear" and "$retLastDay-$retMonth-$retPrvYear";
END
)

Related

Pass variables from shell script to SQL

I have an SQL statement file 1.sql:
set pages 0
set head off
set feed off
select $1 from
(
select $1 from user_tab_partitions
where table_name = 'test'
order by partition_position desc
)
where rownum = 1;
and I would like to execute the same SQL statement in a shell script, 1.sh:
#!/bin/ksh
username="test"
passwrd="testpass"
partition_name=$1
partition_position=$2
PARTNAME=`sqlplus -s $username/$passwrd << EOT
#1.sql $1
exit
EOT`
echo $PARTNAME
PARTPOS=`sqlplus -s $username/$passwrd << EOT
#1.sql $2
exit
EOT`
echo $PARTPOS
--
So, basically what I'm doing is executing the same SQL but with different inputs.
and I don't know how to pass these variables from SHELL script to the SQL script.
What should I change in my code???!!
Thanks for your time!
/Hesi
You need to change your SQL Script from $1 to &1. The $1 will on work if you imbed the SQL into the actual script here doc.
set pages 0
set head off
set feed off
select &1 from
(
select &1 from user_tab_partitions
where table_name = 'test'
order by partition_position desc
)
where rownum = 1;

How to run sql script in an anonymous block?

Is it possible to run an sql script in an anonymous block?
I would like to be able to conditionally run an sql script.
#!/bin/bash
.
.
.
`sqlplus -S /nolog > log3 << EOFSQL
connect ${userName}/${userPassword}#${urlDataBase};
set serveroutput on
set pagesize 0
set feedback off
set verify off
set heading off
set wrap off
set linesize 150
DECLARE
lv_error VARCHAR2(100):='';
BEGIN
SELECT TRIM(STATUS) INTO lv_error FROM tab1
WHERE ...
IF lv_error NOT LIKE 'ERROR%' THEN
START $(pwd)/script.sql;
/
END IF;
END;
/
In your case it is better to write a PL/SQL procedure and invoke it from the shell script. That way, it is easier to conditionally call the second sql function/procedure.
Or, if you want to keep the logic in shell script, spool the output of the first SQL and then read it and call the second sql script.
Something like this.
#!/bin/bash
.
.
.
sqlplus -S /nolog > log3 << EOFSQL
connect ${userName}/${userPassword}#${urlDataBase};
spool spool_out.txt
set linesize 150
DECLARE
lv_error VARCHAR2(100):='';
BEGIN
SELECT TRIM(STATUS) FROM tab1
WHERE ...
END;
/
EOFSQL
errorPresent=`cat spool_out.txt|grep "ERROR"`
if [ ! -z $errorPresent ]
the
#Call $(pwd)/script.sql;
fi

variable value not assigned in cronjob

I have a code which when executed manually ( via this command i.e. ./script.sh ) assigns the query result to a variable but when it is executed automatically via crontab then the query result is not assigned to the variable.
Please find below the code:
diff=0;
diff=`sqlplus -s user/pswd#leadb2 << END
set pagesize 0 feedback off verify off heading off echo off;
SELECT (to_Date($timeRightNow,'YYYYMMDDHH24MISS') - to_date($timeoffile,'YYYYMMDDHH24MISS') ) * 24 * 60
difference_in_minutes
from dual;
END`
echo "Difference is $diff ">>/backup2/softdev/settlement/p.txt
It usually happens because your cron is not aware of your variables initialized in .profile. Even the path for sqlplus is not available, when you run this script via cron. So, to fix the issue, set the cron job in below format, and it will work fine.
00 * * * * . ~/.profile && /home/absolut_path_to_script.sh > /home/log_file_path.txt
i have done it as cron doesnot know the path of SQLPlus so it does not execute the query as soon as the path is given to cron the job responds perfectly
Here is the solution:
ORACLE_HOME=/oracle/app/oracle/product/11.2.0/db_1
export ORACLE_HOME
dateToday=date +%Y%m%d%H%M%S
diff=0;
timeRightNow='20170519180000'
timeoffile='20170519175500'
diff=$ORACLE_HOME/bin/sqlplus -s user/paswd#leadb2 << END
set pagesize 0 feedback off verify off heading off echo off;
SELECT (to_Date($timeRightNow,'YYYYMMDDHH24MISS') - to_date($timeoffile,'YYYYMMDDHH24MISS') ) * 24 * 60
difference_in_minutes
from dual;
END
echo "Difference is $diff ">>/backup2/softdev/settlement/p.txt

How to execute a query stored in a variable in SQL*Plus

Is there any way to pass a query to SQL*Plus through a variable?
I'm aware SQL*Plus has the capability to execute a file like:
sqlplus user/pass#db #filename
Within a kornshell script I'm trying to do:
query="select * from dual;"
sqlplus user/pass#db $query
There might have solution to do that BUT I can achieve the same goal using the following method.
[oracle#myserver Desktop]$ $ORACLE_HOME/bin/sqlplus -s jay/passsword#db <<!
select * from dual;
exit
!
D
-
X
Update, you can store the returned result in a variable as shown below.
query="select * from dual;"
var=$($ORACLE_HOME/bin/sqlplus -s jay/pass#db <<!
set pages 0
set head off
set feed off
$query
!
);

Store SQL query string into variable BASH

I have a select statement inside a bash script that returns the latest date in the DB. I run this query 4 times so I want to define it just once and assing the text to a variable.
#!/bin/bash
linux commands;
database_date=$(sqlplus -s/nolog $USER/$USER#BRMDPP <<END
set pagesize 0 feedback off verify off heading off echo off;
SELECT ...
exit;
END
)
commands that change the database date;
last_date=$(sqlplus -s/nolog $USER/$USER#BRMDPP <<END
set pagesize 0 feedback off verify off heading off echo off;
SELECT ...
exit;
END
)
commands that change the database date;
How can I store this big string $(sqlplus ... into one variable and use it again?
Thank you
One way would be to make use of a function:
foo() {
sqlplus -s/nolog $USER/$USER#BRMDPP <<END
set pagesize 0 feedback off verify off heading off echo off;
SELECT ...
exit;
END
}
and later invoke it by saying:
value=$(foo)
In order to get the value returned by the function, say echo "$value" (note that quoting variables is important).