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
)
Related
This is my shell script.
echo "Start";echo #/opt/apps/Tests/SQLDir/Test1.sql | sqlplus Db1/Db1#//maydomain:port/abc;echo "Finish";
echo "Start";echo #/opt/apps/Tests/SQLDir/Test2.sql | sqlplus Db1/Db1#//maydomain:port/abc;echo "Finish";
I have 30 .sql files like this, added in one .sh file which results 30 .csv files
Test1.sql has
SPOOL /opt/apps/Tests/OF/output1.csv REPLACE;
select name from username where id = 10 and Sname is not NULL and ROWNUM < = 50000;
Test2.sql has
SPOOL /opt/apps/Tests/OF/output2.csv REPLACE;
select strname,ctyname from addr where city = 'NYC' and ROWNUM < = 50000;
My expected OP in output1.csv is
name
Abc
xyz
pqr
My expected OP in output2.csv is
strname | ctyname
10-AP NYC
11-KP MCH
90-ZP SDK
right now I am getting weird o/p in csv
name
-------------------------------
Abc
xyz
pqr
name
-------------------------------
TYU
KLH
50000 rows selected.
SQL>
So is there any way to remove those additional lines [--------- and 50000 rows selected.] with shell script/sql code?
And while executing shell script all sql result rows are getting printed on screen. how to avoid that?
Thanks in advance.
Following SQL*Plus command should do the job:
set markup csv on delimiter ' ' quote off
set feedback off
I must say, your method of passing the name of a script to sqlplus is the strangest I've ever seen. The usual practice (given your names) would be:
sqlplus Db1/Db1#//maydomain:port/abc #/opt/apps/Tests/SQLDir/Test1.sql
I don't see where your 'echo Start' and 'echo finished' accomplish anything, since there is no clarifying info coming along with it.
It looks to me like what you want in your scripts would be
set echo off trimsp on head off pagesize 0
spool /opt/apps/Tests/OF/output2.csv replace
select strname,ctyname from addr where city = 'NYC' and ROWNUM < = 50000;
spool off
BTW, 'spool' is a sqlplus command - a directive to sqlplus itself, not a sql statement. As such, it does not need a semi-colon at the end.
-- edit
Example of using environment variables on sqlplus command line:
username=scott
userpw=tiger
server=myserver
port=1521
dbname=mydb
sqlplus $username/$userpw#//$server:$port/$dbname
Though I would question why you need to set them as variables.
And I prefer to use tnsnames rather than ezconnect.
I have a file test.sh in which i have a query which gives me the count of total records in the table, as shown below:
Query:
echo db2 -x "select count(*) from testableā
Now I want to assign the whatever value it returns after executing it to the variable as totalRecords using the Unix Shell Script.
#!/bin/bash
cnt=`db2 -x "select count(*) from syscat.tables" `
echo "Counter is: ${cnt}"
Counter is: 474
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
Below is the Perl script that I have written
my $COUNT_1;
my $parameter1 = 'PU_CLERK';
$COUNT_1 = `sqlplus -s hr/password\#dbname\#sql_script.sql $parameter1`;
SQL SCRIPT:
select count(*) from employees
where job_id <> '&1'
and salary > 9000
and commission_pct is not null
order by first_name desc
/
exit;
When I run this query by passing the argument &1 it is giving me a string with an error message. But when I run the same query by hardcoding I'm getting the output properly (the count is 15 which is the correct answer).
select count(*) from employees
where job_id <> 'PU_CLERK'
and salary > 9000
and commission_pct is not null
order by first_name desc
/
exit;
I'm not able to understand where I'm going wrong. How do I pass parameters in Perl. We used to do the same way in shell script and it was working absolutely fine.
EDIT:
This is the error message im getting
perl call_sql.pl
value of first variable isold 2: whe
re job_id <> '&1'
new 2: where job_id <> 'PU_CLERK'
15
So its basically not printing the 15 value its printing all those string also when i use '&1' in my sql script
EDIT2:
Hi Guys finally it is working. In my sql code instead of giving '&1' i gave '$1' Now i want to know is $1 of some significance in Perl? Thanks..
I don't know the answer to your current problem, but using the DBI module is the better solution, so I wrote a sample script to get you started. You may need to tweak some things to get it to work.
use strict;
use warnings;
use DBI;
my $dbname = "mydb";
my $user = "foo";
my $passwd = "bar";
my $dbh = DBI->connect("dbi:Oracle:$dbname", $user, $passwd)
or die $DBI::errstr;
my $parameter1 = 'PU_CLERK';
my $statement = "select count(*) from employees
where job_id <> ?
and salary > 9000
and commission_pct is not null
order by first_name desc";
my $sth = $dbh->prepare($statement) or die $dbh->errstr;
$sth->execute($parameter1) or die $sth->errstr;
while (my $row = $sth->fetchrow_arrayref) {
print "#$row"; # or whatever you want to do with it
}
$dbh->disconnect or warn $dbh->errstr;
This has nothing with perl.
Proof: make an shell script, say mytest.sh with the next content:
#!/bin/bash
echo "$0: Got $# args" >&2 #to stderr
i=0
for arg
do
let i++
echo "$0: arg($i)=$arg=" >&2 #to stderr
done
echo "15" #result to stdout
make it executable, with chmod 755 mytest.sh
Now modify your perl script as:
my $COUNT_1;
my $parameter1 = 'PU_CLERK';
$COUNT_1 = `./mytest.sh -s hr/password\#dbname\#sql_script.sql $parameter1`;
print "script returned: $COUNT_1\n";
run it
$ perl script.pl
result:
./mytest.sh: Got 3 args
./mytest.sh: arg(1)=-s=
./mytest.sh: arg(2)=hr/password#dbname#sql_script.sql=
./mytest.sh: arg(3)=PU_CLERK=
script returned: 15
e.g. the perl
correctly run the external script
correctly passes the arguments to it
so, search for the error in the sqlplus doccumentation...
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.