When sending variables from linux command to a plsql block, i am calling the program as sqlplus user/pass#db #file param1 and within the file i can use the param1 as &1.
Now what happens on the other way around? If you want to have a file which will execute sth. sqlplus user/pass#db and inside this file you have select number from table and this results to a single number out.
When this executes, how can i send this number back to linux so that to use it within my sell script?
i.e. export NUMBER=the number i got from sql
You can do this using here document:
v1=`$ORACLE_HOME/bin/sqlplus -S /nolog > ${logfile} 2>&1 << EOF
connect test/passwd#sid
SET FEED OFF;
SET TERMOUT ON;
SET VERIFY OFF;
SET ECHO OFF;
SET HEAD OFF;
SELECT sysdate from dual FROM DUAL;
EXIT
EOF`
echo $v1
Related
How to call a sql query using bash shell script. I tried the below but seems there is some syntax error:
#!/bin/sh
LogDir='/albt/dev/test1/test2/logs' # log file
USER='test' #Enter Oracle DB User name
PASSWORD='test' #Enter Oracle DB Password
SID='test' #Enter SID
sqlplus -s << EOF > ${LogDir}/sql.log
${DB_USER_NAME}/${DB_PASSWORD}#${DB_SID}
SELECT count(1) FROM dual; # SQL script here to get executed
EOF
var=$(SELECT count(1) FROM dual)
I'm getting - unexpected token error
#!/bin/sh
user="test"
pass="test"
var="$1"
sqlplus -S $user/$pass <<EOF
SELECT * FROM tableName WHERE username=$var;
exit;
EOF
I'm getting - sqlplus: command not found -- when I run the above script
Can anyone guide me?
In your first script, one error is in the use of count(1). The whole line is
var=$(SELECT count(1) FROM dual)
This means that the shell is supposed to execute a program named SELECT with the parameters count(1), FROM and dual, and stores its stdout into the variable var. I think you want instead to feed a SELECT command into sqlplus, i.e. something like
var=$(sqlplus .... )
In your second script, the error message simply means that sqlplus can not be found in your path. Either add it to the PATH or provide the absolute path to the command explicitly.
I am running the following shell script which calls a .SQL file, that contains a list of DELETE statements. On executing ./delete_crr_input_purge.sh, I get the following message "Nothing in SQL buffer to run.". The .SQL file gets executed anyway but what is wrong with my code in the shell script?
#!/bin/ksh
#
# #(#)Copyright All Rights Reserved.
# #(#) $Id: run_drm_utility.sh $
# Setup common environment
. `dirname $0`/db_env.sh
cd `dirname $0`
echo "Enter the SHBA Atomic DB User Name:"
read USERNAME
echo "Enter the SHBA Atomic DB User Password:"
read PASS
cnt=`sqlplus -s /nolog <<-EOF
WHENEVER OSERROR EXIT 9;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
connect $USERNAME/$PASS#$ORACLE_SID
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
#delete_crr_input_purge.sql;
commit;
EOF`
echo [$cnt]
return $?
I was able to fix this error by removing comments and occurrences of "/" from my .SQL file.
Also, I made sure that each of my SQL statements were in one line, one below the other. Also, no commit statement inside the .SQL file.
I'm not getting any output to my FILE for query. while I'm running in oracle I can see the counts.
Can someone please let me know what am I doing wrong?
#!/bin/bash
ORACLE_HOME=*path*
TNS_ADMIN=*path*
export ORACLE_HOME
export TNS_ADMIN
FILE="/tmp/score_cnt.txt"
sqlplus -S user/pass#service<< EOF
spool $FILE
select count(*) from score_tbl
spool off
exit;
EOF
Seems like passing the *nix variable to SQL*Plus is messing the things around here.
As far as I understand, you wish to pass the file name in the script, then the easiest mechanism would be to define it as SPOOL File directly (instead of getting it parametrized).
Moreover you can add some really useful SET parameters to beautify the output.
sqlplus -S user/pass#service << EOF
SET LINESIZE 32000
SET PAGESIZE 0
SET TRIMSPOOL ON
SET TRIMOUT ON
SET WRAP OFF
SET TERMOUT OFF
spool /tmp/score_cnt.txt
select count(*) from score_tbl;
spool off
EOF
PS - EOF doesn't require additional exit in sqlplus & select
statement must end with a ;
I have below code in bash:
#/!bin/bash
USERS=tom1,tom2,tom3
and I want to drop all users from my variable "USERS" via sqlplus
#/!bin/bash
USERS=tom1,tom2,tom3
sqlplus -s system/*** <<EOF
*some code*
DROP USER tom1 CASCADE;
DROP USER tom2 CASCADE;
DROP USER tom2 CASCADE;
EOF
pls help
Splitting in database using sql / plsql by using the USERS variable is complex and requires understanding of REGEXP functions and I will not recommend that to you. Moreover, it would also require Dynamic Sql to execute a drop query.
I would suggest you to split it within the shell script,create a script and execute it in sqlplus
USERS="tom1,tom2,tom3"
echo ${USERS} | tr ',' '\n' | while read word; do
echo "drop user $word;"
done >drop_users.sql
sqlplus -s system/pwd <<EOF
#some code
#drop_users.sql
EOF
Your code is OK except for DDL commands for Oracle DB which are derived from USERS parameter of the script file, call userDrop.sh. To make suitable relation with USERS parameter and DB, an extra file (drpUsr.sql) should be produced, and invoked inside EOF tags with an # sign prefixing.
Let's edit by vi command :
$ vi userDrop.sh
#!/bin/bash
USERS=tom1,tom2,tom3
IFS=',' read -ra usr <<< "$USERS" #--here IFS(internal field separator) is ','
for i in "${usr[#]}"; do
echo "drop user "$i" cascade;"
done > drpUsr.sql
#--to drop a user a privileged user sys or system needed.
sqlplus / as sysdba <<EOF
#drpUsr.sql;
exit;
EOF
Call as
$ . userDrop.sh
and do not forget to come back to command prompt by an exit command of DB.
I am using below command to get result for my SQL query.
su - postgres -c 'psql -d dbname' with stdin "COPY ( my SQL query ) TO STDOUT WITH CSV HEADER"
This works fine on my server but on different machine it is printing bash warning with output of SQL query.
For example -
/etc/profile: line 46: HISTSIZE: readonly variable
/etc/profile: line 50: HISTCONTROL: readonly variable
/etc/profile.d/20-tmout.sh: line 1: TMOUT: readonly variable
/etc/profile.d/history.sh: line 6: hcmnt_tty: readonly variable
name
abc
Please let me know anyway so that I can skip above warning messages and only get data.
If I would like to use /dev/null in this case how to modify above command to get data only.
if what you mean is "how to discard only error output?", the way to go is to redirect the standard error stream to oblivion (/dev/null), like so:
your-command 2>/dev/null
that way, if the command outputs data to standard out, it passes through, but any output to the standard error socket is discarded, so you won't see these error messages.
by the way, 2 here is a shorthand file descriptor for the standard error.
Sorry this is untested, but I hit this same error, your db session isn't read/write. You can echo the statements to psql to force a proper session as follows. I'm unsure as to how stdin may be effected
echo 'SET TRANSACTION READ WRITE; SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE ; COPY ( my SQL query ) TO STDOUT WITH CSV HEADER' | su - postgres -c 'psql -d dbname' with stdin
caution - bash hack
su - postgres -c 'psql -d dbname' with stdin "COPY ( my SQL query ) TO STDOUT WITH CSV HEADER" | grep -v "readonly"