How to pass variables in sqlplus in bash command - bash

Here is may problem : I have inline sqlplus call in my bash file and I would like to pass it a parameter
this code is what I'm trying
c_id=`sqlplus -S $login/$password $id << EOF
set pagesize 0
set verify off
set head off
set feedback off
SELECT id from bdd.table where ID not in (select id from bdd.TMP_table) and id > &1 and ROWNUM <= 1000 order by id;
exit;
EOF`
how can I use my $id parameter in my where statement (&1)?

Just change &1 to $id. For example:
id=101
c_id=`sqlplus -S $login/$password << EOF
set pagesize 0
set verify off
set head off
set feedback off
SELECT id from bdd.table where ID not in (select id from bdd.TMP_table) and id > $id and ROWNUM <= 1000 order by id;
exit;
EOF`
Bash will perform parameter substitution. $id will be substituted with the actual value of the parameter i.e. 101 in this case, before sqlplus runs.

Related

Script runs in standalone but does not work in crontab

Here is the script which works well when executed in standalone but fails when scheduled as a cronjob,
#!/bin/bash
# TARGET TABLE COUNT FOR Server
#
CURRENTTARGETREF=$(sqlplus -s $DB_USER/$DB_PASS << END
set pagesize 0 feedback off verify off heading off echo off;
SELECT CURRENTTARGETREF FROM PARAMETER
exit;
END
)
TABLENAME="TARGET$CURRENTTARGETREF"
TARGETCOUNT=$(sqlplus -s $DB_USER/$DB_PASS << END
set pagesize 0 feedback off verify off heading off echo off;
SELECT COUNT(*) FROM $TABLENAME
exit;
END
)
echo "Current Target table count in server: $TARGETCOUNT"
#
# COUNTER TABLE COUNT FOR server
#
S1=`echo "SELECT COUNT(*) FROM COUNTER WHERE SERVERID=1;" | sqlplus $DB_USER/$DB_PASS | sed -n '/COUNT(\*)/{n;n;p}'`
S2=`echo "SELECT COUNT(*) FROM COUNTER WHERE SERVERID=2;" | sqlplus $DB_USER/$DB_PASS | sed -n '/COUNT(\*)/{n;n;p}'`
#
echo "Current Counter table count with SERVERID '1' in server:$S1"
echo "Current Counter table count with SERVERID '2' in server:$S2"
#
below is the cronjob for this script
31 01 * * * DS=$(date +\%Y-\%m-\%d); /path/Databasecount.sh >> /path/test.out.$DS.txt 2>&1
And i wanted to send the output of the script to mail and could you someone please help me on this.

How to use a variable from Bash into SQLPLUS?

I'm trying to write a script which would accept the customer ID using BASH ( using a basic read command ) and then I want to use that BASH variable in my SQLPLUS query. How can I do that ? I'm trying to use below format, but it is not working.
echo "Enter Customer ID :- ";
read Customer
sqlplus username\password#host
select first_name from customer where customer_id = $Customer;
quit
exit
Typically, you would do:
echo "select first_name from customer where customer_id = $Customer;" | sqlplus username\password#host
If you want to run multiple queries, it is common to use a heredoc:
cat << EOF | sqlplus username\password#host
select first_name from customer where customer_id = $Customer;
select first_name from customer where customer_id = $Customer;
EOF
edited in response to query in comment:
to store the result of any command in a variable you can use process substitution. var=$( cmd ). In the heredoc case, the syntax is:
var=$( cat << EOF | sql...
query
query
EOF
)

How to fetch more than one column value from oracle select query to shell variable

I am trying to fetch a row with more than one column value to different shell variables. Infact I found that at a time all the column values can be stored to single shell variable. But how can I put those column values to seperate shell variables. Below is an example I am trying for time being
function sqlQuery {
sqlplus -S shiyas/********* <<'EOF'
set heading OFF termout ON trimout ON feedback OFF
set pagesize 0
SELECT name,open_mode from v$database;
EOF
}
OUTPUT="$( sqlQuery )"
echo $OUTPUT
Here I am getting the output as
ORCL READ WRITE
But my requirement is column values ORCL, READ WRITE should get assigned to different shell variable.
I tried the below of parsing.
echo "$OUTPUT" | while read name open_mode
but it was throwing unexpected end of file error.
-bash-3.2$ sh call_sql_col_val_1.sh
ORCL READ WRITE
call_sql_col_val_1.sh: line 18: syntax error: unexpected end of file
Please let me know what concept I can use to fetch a single row column values to different shell variables.
I do this via eval myself:
oracle#******:/*****> cat test.sh
#!/bin/bash
function sqlQuery {
sqlplus -S / as sysdba <<'EOF'
set heading OFF termout ON trimout ON feedback OFF
set pagesize 0
SELECT name,open_mode from v$database;
EOF
}
eval x=(`sqlQuery`)
NAME=${x[0]}
OPEN_MODE="${x[1]} ${x[2]}"
echo NAME IS $NAME
echo OPEN_MODE IS $OPEN_MODE
So we are running the same function you have above, passing it into x and running it through eval to handle the delimitation. Then you have an array and call call is as such: x[0] for the first item, for example.
Output is:
oracle#******:/******> sh test.sh
NAME IS ******
OPEN_MODE IS READ WRITE

Check if value within column exists, if not create the column

I need to check if one of the columns in my db contains specific value. If it doesn't I want to create that row with folowing values:
#!/bin/bash
#
MODEL=$1
if true (SELECT * FROM table.STATISTICS
WHERE MODEL = '$MODEL' )
do this (INSERT INTO table.STATISTICS('$MODEL',0,SYSDATE,0,SYSDATE,0); )
You could use a merge for this, run through SQL*Plus as a 'heredoc', so you don't have to do a separate count operation; the merge will do that for you effectively:
#!/bin/bash
MODEL=$1
sqlplus -s /nolog <<!EOF
connect user/pass
merge into statistics s
using (select '${MODEL}' as model, 0 as num1, sysdate as date1,
0 as num2, sysdate as date2 from dual) t
on (s.model = t.model)
when not matched then
insert (s.model, s.num1, s.date1, s.num2, s.date2)
values (t.model, t.num1, t.date1, t.num2, t.date2);
!EOF
But using your real column names, obviously. It's better to list them explicitly even for a plain insert.
get_count () {
sqlplus -s username/pass <<!
set heading off
set feedback off
set pages 0
select count(model) from statistics
where model='$MODEL';
!
}
count=$(get_count $1)
if [ "${count:-0}" -eq 0 ]; then
echo "its zero"
sqlplus -S username/pass << EOF
whenever sqlerror exit 1;
set echo on
set verify off
INSERT INTO table.STATISTICS VALUES('$MODEL',0,SYSDATE,0,SYSDATE,0);
exit;
EOF
fi

Modify oracle sql query output format

I want to change output format of my oracle sql script.
Consider I have a script named: active_user.sh which inside it I just write my query. Now the problem is when I bash the script the output displayed without caption and only values are shown.
The script is:
export CONNECT_STRING=$1
if [ x$2 == x ]
then echo First Parameter is connection string to DB and Second parameter have to be ORACLE_HOME variable && exit 1
else export ORACLE_HOME=$2
fi
export ORACLE_SID=OMEGA #fake
export PATH=$ORACLE_HOME/bin:$PATH
RAND=$$
sqlplus -s /nolog <<-EOF > /tmp/${RAND}.sql_out.temp
connect $CONNECT_STRING
set HEADING OFF
set PAGESIZE 0
set linesize 120
col metric_name format a40
col value format 999999990.9999
select count(*) from v\$session where username is not null and status='ACTIVE';
EOF
cat /tmp/${RAND}.sql_out.temp
And this is the command to run the script and the output is:
[root#oracle-test scripts]# ./active_users.sh "ora/orapass123#mydb" /opt/oracle/instantclient_11_2
1
23.0000
But when I run the query in sqlplus it returns something like this:
COUNT(*)
----------
1
If you want to print the column headings, you have to put set HEADING ON.
You can also using SPOOL command, something like this (sorry, I can't testint now):
spool /tmp/${RAND}.sql_out.temp
set heading on
set pagesize 1000
set tab on
set linesize 120 wrap off
column "yourcount" format a40
col metric_name format a40
col value format 999999990.9999
select count(*) yourcount from v\$session where username is not null and status='ACTIVE';

Resources