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

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

Related

Is there a hive condition to exit out if the table count is zero or equals a number?

I am using shell to trigger hive and run the queries in hql file where there are more than 10 queries.
My question : Is there a way were we can exit out of hive and return back to shell if my first query returns zero.
For better understanding :
IF select COUNT(*) from mytable is 0 then exit ELSE continue ;
You can move this logic to the shell:
rowcount=$(hive -S -e "select COUNT(*) from mytable")
if [ $rowcount == 0 ] ;then
exit
else echo ok; #run your script here
fi;
Also in Hive you can use assert_true() function to check boolean expression. If False, the script will fail with exception: ASSERT_TRUE(): assertion failed:
select assert_true(COUNT(*)!=0) from mytable

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

Variable won't resolve inside PL-SQL statement

I am trying to pass a SQL command to the SQL*Plus command-line program (Oracle) in my KornShell (ksh) script, but my $MY_VAR variable seems to be failing to resolve. $MY_VAR is a string value.
sqlplus -s << EOF >> $LOG_FILE
$MY_SCHEMA
UPDATE my_table SET run_flag = 'I', start_time = to_char(sysdate, 'DD-Mon-YYYY HH24:MI:SS') WHERE (process_id = '$MY_VAR' AND run_flag != 'F');
COMMIT;
EOF
I can successfully echo out the $MY_VAR variable, and so I can see that the variable is populated, but it does not seem to be resolving when inserting the variable into the SQL command which I am providing as an argument to the SQL*Plus program. The log file for the script simply outputs:
0 rows updated. Commit complete.
The SQL seems to be valid as we can successfully execute the command in SQL Developer (albeit with a hardcoded value for $MY_VAR).
Any ideas on what I am missing here?
Thank you
Try this:
sql="$MY_SCHEMA
UPDATE my_table SET run_flag = 'I', start_time = to_char(sysdate, 'DD-Mon-YYYY HH24:MI:SS') WHERE (process_id = '$MY_VAR' AND run_flag != 'F');
COMMIT;"
print "$sql"
sqlplus -s <<<"$sql" >> $LOG_FILE
Does the sql look correct? If it does and zero rows are updated, your where clause must be selecting zero rows.
Your version of ksh may not have the <<< here-string syntax. In that case:
print "$sql" | sqlplus -s >> $LOG_FILE

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';

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