Script runs in standalone but does not work in crontab - shell

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.

Related

Sqlplus script part showing "Badly placed ()'s." error

I'm writing a script and have a problem when trying to get a date from the table. I'm having problem storing it into a variable. I always get the error:
Badly placed ()'s.
The variable TIMEFRAME is "D" and the shell actually gets into the IF, also the password is also not the problem as I use it to connect manually and check the query (no problems here).
This is the part of the script where I'm having problems.
#!/bin/csh -f
if ( $TIMEFRAME == "D" ) then
set TIMEBEG = `sqlplus -s $PASSWORD << EOF \
set head off; \
set feed off; \
select to_char(trunc(sysdate) - 1,'YYYYMMDD') from dual; \
exit; \
EOF`
set TIMEEND = $TIMEBEG"235959"
set TIMEBEG = $TIMEBEG"000000"
endif
I also tried to store it on a file, same problem
#!/bin/csh -f
set tmp_file=/tmp/tmp.$$
if ( $TIMEFRAME == "D" ) then
sqlplus -s $PASSWORD > $tmp_file << EOF \
set head off \
set feed off \
select to_char(trunc(sysdate) - 1,'YYYYMMDD') from dual; \
exit; \
EOF
set TIMEBEG=`cat $tmp_file`
set TIMEEND = $TIMEBEG"235959"
set TIMEBEG = $TIMEBEG"000000"
endif
I tried different solutions but with the same problem, tried without semi-colons, without the SETs, to put it on a single line, I'm out of Ideas.
When trying with -xvf this is what I get when I get into the part:
if ( $TIMEFRAME == "D" ) then
if ( D == D ) then
sqlplus -s $PASSWORD > $tmp_file << EOF set head off set feed off select to_char ( trunc ( sysdate ) - 1,'YYYYMMDD' ) from dual ; exit ; EOF
Badly placed ()'s.
Any ideas? This is running on Amazon Linux
I'm not sure you can use a here-doc inside backticks in C shell.
Write the sqlplus input to a file, rather than writing the whole sqlplus command.
#!/bin/csh -f
set tmp_file=/tmp/tmp.$$
if ( $TIMEFRAME == "D" ) then
cat > $tmp_file <<EOF
set head off
set feed off
select to_char(trunc(sysdate) - 1, 'YYYYMMDD') from dual;
exit;
EOF
set TIMEBEG = `sqlplus -s $PASSWORD < $tmp_file`
set TIMEEND = $TIMEBEG"235959"
set TIMEBEG = $TIMEBEG"000000"
endif

Changing multiple actions chained into sqlplus to for loop in a bash script

I have this script which is obviously inefficient:
#!/bin/sh
for i in $(seq 1 10);
do
echo "CREATE TABLE testbenny_$i (id NUMBER NOT NULL);
! sleep 10
select * from testbenny_$i;
! sleep 10
select * from testbenny_$i;
! sleep 10
select * from testbenny_$i;
! sleep 10
select * from testbenny_$i;
! sleep 10
DROP TABLE testbenny_$i;" | sqlplus system/passwd &
done
I have one repetitive action I tried to enclose in a FOR loop but couldn't.
select * from testbenny_$i;
! sleep 10
I can't find the correct syntax to change it to a FOR. Working on Oracle 12.
Try the oracle sleep method as following:
#!/bin/sh
for i in $(seq 1 10);
do
echo "CREATE TABLE testbenny_$i (id NUMBER NOT NULL);
sys.DBMS_SESSION.sleep(10);
Begin
For var in 1..4 loop
select * from testbenny_$i;
sys.DBMS_SESSION.sleep(10)
End loop;
End;
/
DROP TABLE testbenny_$i;" | sqlplus system/passwd &
done
I have given just an example of how to use sys.DBMS_SESSION.sleep(10) method. Use it in your code according to your requirement.

Shell Script piping

#!/bin/sh
output=ANIL;
#
# Ask user for database inputs
#
echo -n "Enter Database Server Hostname: "
read dba_host
echo -n "Enter Database SID: "
read dba_sid
echo -n "Enter DBA User: "
read dba_usr
echo -n "Enter DBA password: "
read dba_pwd
echo -n "What daemon are we using: "
read daemon_str
#
# Loop to connect to database and exit if something is found
#
while :
do
output=`sqlplus $dba_usr/$dba_pwd#$dba_sid <<+ | grep '^-' | sed 's/-//'
set serveroutput on
DECLARE
command VARCHAR2(50);
return_name VARCHAR2(30);
value VARCHAR2(10000);
status INT;
system_time TIMESTAMP := SYSTIMESTAMP;
WHILE TRUE
BEGIN
status := DBMS_PIPE.RECEIVE_MESSAGE($daemon_str);
IF status = 0 THEN
DMS_PIPE.UNPACK_MESSAGE(command);
END IF;
IF command = "STOP" THEN
DBMS_OUTPUT.PUT_LINE('STOP was encountered') >> file.log;
DBMS_OUTPUT.PUT_LINE(system_time) >> file.log;
BREAK
ELSIF command = "SYSTEM" THEN
DBMS_PIPE.UNPACK_MESSAGE(return_name);
DBMS_PIPE.UNPACK_MESSAGE(value);
EXIT
$value
ELSIF command = "SQL"
DBMS_PIPE.UNPACK_MESSAGE(return_name);
DBMS_PIPE.UNPACK_MESSAGE(value);
EXECUTE IMMEDIATE value;
ELSE
nap(10)
EXCEPTION
WHEN OTHERS THEN
dbms_ouput.put_line('Unknown Input Error') >> file.log;
DBMS_OUTPUT.PUT_LINE(system_time) >> file.log;
DBMS_PIPE.PACK_MESSAGE('done');
DBMS_PIPE.PACK_MESSAGE(status);
status := DBMS_PIPE.SEND_MESSAGE(return_name,10);
END;
dbms_output.put_line(chr(10) || '-' || command);
END;
/
exit
+`
echo $output
done
I am trying to convert a c code block to what you see now a shell script block. I am just a beginner in this coding language and was wanting to know if anyone is seeing something I am not. To sum up what I am trying to accomplish is ask user for the oracle database they want to connect to then keep connection and receive things through pipe. Then the usual of unpacking, outputting errors and such. Then sending it back through same pipe. Any input on possible syntax or anything at all that could be causing this to constantly echo out nothing but blank lines from while loop.

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

How to pass variables in sqlplus in bash command

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.

Resources