Oracle sqlplus execute sql script from command line while passing parameters to the sql script - oracle

I have one script script.sql which I want to execute from command line using oracle and passing it two parameters, as shown below
sqlplus user/pass # script.sql my_parameter1_value my_parameter2_value
What should it be in script.sql in order to be able to run it with the parameter values?

The solution can be prepared looking at oracle blogs:
https://blogs.oracle.com/opal/sqlplus-101-substitution-variables#2_7
For the question above, the solution would be to create a script.sql like this:
DEFINE START_VALUE = &1;
DEFINE STOP_VALUE = &2;
SELECT * FROM my_table
WHERE
value BETWEN &&START_VALUE AND &&STOP_VALUE;

I wanted to run a script that would return all orders raised during the last seven days. Here's how...
the script
SELECT * FROM orders_detail WHERE order_date BETWEEN '&1' AND '&2';
EXIT;
the command
sqlplus ot/Orcl1234#xepdb1 #"/opt/oracle/oradata/Custom Scripts/orders_between_dates.sql" $(date +%d-%b-%Y -d '-7 days') $(date +%d-%b-%Y)
Hope that helps someone. Luck.

Related

SQLPLUS connection to different dbs

Hello i want to connect to following dbs in loop and execute statements on each:
conn support/support#sp0666to
conn support/support#sp0667to
conn support/support#sp0668to
Is there any way to do this in sqlplus?
Thank you for your answers in advance!
Create one script (doWork.sql) that contains the majority of what you want to do:
conn &1/&2#&3
select EMPLOYEE, AUTHORIZED, TIME, DAT, WORKSTATION
from EMPLOYEE
where status = 25;
In a separate script (goToWork.sql):
set lines 1500 pages 10000
set colsep ';'
set sqlprompt ''
set heading on
set headsep off
set newpage none column tm new_value file_time noprint
select to_char(sysdate, 'DDMMYYYY_HH24.MI') tm from dual;
accept user
accept pass
spool C:\Users\NANCHEV\Desktop\parked.csv
##doWork &user &pass sp0666to
##doWork &user &pass sp0667to
##doWork &user &pass sp0668to
spool off;
exit
If you want separate files, then move the two spool commands to the doWork.sql file.
Assuming you want to run the same set of queries for each database, I'd create a script file (e.g. main_statements.sql) containing those statements.
Then, if the list of databases was static, I'd create a second script file (e.g. run_me.sql) in the same directory, with contents along the lines of:
connect &&user/&&password#db1
##main_statements.sql
connect &&user/&&password#db2
##main_statements.sql
connect &&user/&&password#db3
##main_statements.sql
...
If, however, the databases are static but the list is contained in a database somewhere, then I'd write a script (e.g. run_me.sql) that generates a script, something like:
set echo off
set feedback off
set verify off
spool databases_to_run_through.sql
select 'connect '||username||'/'||password||'#'||database_name||chr(10)||
'##main_statements.sql'
from list_of_databases_to_query;
spool off;
##databases.run_through.sql
N.B. untested. Also, I have assumed that your table contains the usernames and passwords for each db that needs to be connected to; if that's not the case, you'll have to work out how to handle them; maybe they're all the same (in which case, you can hardcode them - or better yet, use substitution variables (e.g. &&username) to avoid having to store them in a plain file. You'd then have to enter them at runtime.
You'll also need to run the script from the same directory, otherwise you could end up with the generated script not being created in the same directory as your main_statements.sql equivalent script.
Yes it's possible, you can use oracle DBLink to connect to different dbs just like your example.

Single command from batch file with sqlplus not working in some cases

I have the following command in a batch file.
set tableName=%1
select count(1) from %tableName% where to_char(DATEVALUE,'yyyy-mm-dd hh24:mi:ss')^>(select to_char(max(DATEVALUE),'yyyy-mm-dd hh24:mi:ss') from FOO_TABLE); | sqlplus !connectionString!
This statement doesn't work. I can see that it connects to the database and then disconnects. But the following works:
select count(1) from %tableName% where to_char(DATEVALUE,'yyyy-mm-dd hh24:mi:ss')=(select to_char(max(DATEVALUE),'yyyy-mm-dd hh24:mi:ss') from FOO_TABLE); | sqlplus !connectionString!
I am guessing the problem could be with the greater than > symbol. I tried ^>,> and \>. None of them works. How can I get this sql statement to work.
(I have connectionString already set in my batch file in earlier lines).
The output in the command line is
Connected to:
Oracle Database ... (more db info)
SQL> Disconnected from Oracle Database ... (more db info)
It looks like you need to escape the ^ escape character as well; depending on exactly how you're running this, either:
... where to_char(DATEVALUE,'yyyy-mm-dd hh24:mi:ss')^^>(select ...
or
... where to_char(DATEVALUE,'yyyy-mm-dd hh24:mi:ss')^^^>(select ...
In a batch file where the query is echoed and piped the triple-escape works:
#setlocal EnableDelayedExpansion
#set connectionString=x/y#z
#set tableName=bar
#echo select count(1) from %tableName% where to_char(DATEVALUE,'yyyy-mm-dd hh24:mi:ss')^^^>(select to_char(max(DATEVALUE),'yyyy-mm-dd hh24:mi:ss') from FOO_TABLE); | sqlplus !connectionString!
Running that batch script shows the statement being run (and erroring in my case with ORA-00942, which is expected). With a single or double ^ it has nothing to run at the SQL prompt and a file is created instead, which seems to be what you're seeing.

Fetching SQL execution plan. PL/SQL Developer = strange behaviour. SQL*Plus = no rows selected

I have a problem with fetching SQL plans.
In the final form, I have to fetch them through PL*SQL.
So I have a bash script, a loop to iterate through sql plan names and parameters, and a code like this:
sqlplus -s /nolog > /dev/null 2>&1 <<EOF
CONNECT BLAH/BLAH#BLAH
*CLEAR AND SET COMMANDS HERE*
VARIABLE RC REFCURSOR;
SPOOL ${BERICHT}_${configArray[0]}.DATA
SET TIMING ON;
EXEC :RC := $aktuellesBericht;
SET TIMING OFF;
PRINT RC;
DISCONNECT
QUIT
EOF
And the second part: (logging in as SYS, but without the SYSDBA permissions, I dont have them and I dont think that I will have them...)
sqlplus -s /nolog > /dev/null 2>&1 <<EOF
CONNECT SYSBLAH/SYSBLAH#BLAH
SPOOL ${BERICHT}_${configArray[0]}.SQLPLAN.TXT
CLEAR BREAK
CLEAR COMP
CLEAR COL
select
sqlplan.operation,
sqlplan.options,
sqlplan.object_name,
sqlplan.cost,
sqlplan.depth
from v\$sqlarea sqlarea,
v\$session sesion,
v\$sql_plan sqlplan
where sesion.sql_hash_value = sqlarea.hash_value
and sesion.sql_address = sqlarea.address
and sqlarea.plan_hash_value = sqlplan.plan_hash_value
and sesion.username = 'BLAH' order by sqlplan.depth;
QUIT
EOF
All I can get from this is *.SQLPLAN.TXT files containing just one sentence: no rows selected
What is strange here, that when I do the same in PL/SQL Developer - i get the same results, BUT when I just click on the Auto Refresh timer button on both SQL windows, both queries are running in parallel, and SOMETIMES the second query (the one to fetch SQL plan) is giving me results. And sometimes it doesnt.
It seems that theese commands need to be run in parallel... or am I missing something?
The sql query in my question was never needed.
All I needed is to write to the admin team to grant me the SELECT premissions on:
V$SQL_PLAN, V$SESSION and V$SQL_PLAN_STATISTICS_ALL
The answer to my question was found here.
I will need a deeper understanding of the problem in the future but for now, FWIK, looking deeper into the dbms_xplan package gave me the idea.
The approach to get the queries from the SYSACC account was the wrong idea. This acc has access to all the queries history and it is hard and painful (if even possible) to husk out the sql plan I needed.

Execute plsql dynamiclly via SSH in remote server (using dynamic login info) and get returned value to executing server

I am trying to execute a dynamic plsql command in a remove machine (say 192.168.x.x) and get it's return value to local machine from where I initiate shell script. I am testing two approaches to do this. But none of them seems to work properly.
Approach - I
in this approach if i supply values for ssh and sqlplus (login user/ip and schema user/ip) via shell variable it won't work. working code with hardcoded value is below.
#!/bin/sh
varfld="SYSDATE"
retVal=`echo "SELECT $varfld FROM dual;" | ssh utility#192.168.x.x 'sqlplus -S utility/pwd' | tail -2 | head -1`
echo "return value 1: "$retVal
Approach - II
In this approach I can pass everything i need in a variable. But the plsql command (i.e value of variable $ssh_execute_command) is not recognized inside plsql. Only hardcoded plsql command gets executed.
P.S.This works fine with vsql with few modification to connect Vertica.
v_server_user=utility
v_server_name=192.168.x.x
ssh_v_schema_name=utility
ssh_v_schema_pwd=pwd
varfld="SYSDATE"
execute_command="SELECT $varfld FROM dual;"
retVal=$(ssh $v_server_user#$v_server_name ssh_v_schema_name=$v_schema_name ssh_v_schema_pwd=$v_schema_pwd ssh_execute_command=\""$execute_command"\" 'bash -s' <<SSHSQLTEXT
sqlplus -S $ssh_v_schema_name/$ssh_v_schema_pwd
SET ECHO OFF
SET HEADING OFF
SET FEEDBACK OFF
SELECT SYSDATE FROM dual;
SSHSQLTEXT
)
echo "return value 2: "$retVal
Queries
1. How can we make sql command passed in a variable make work inside pqlplus? or
2. How can we pass required values for ssh and sqlplus (login user/ip and schema user/ip) dynamically and make it work?
The sql statement "SELECT SYSDATE FROM dual;" used here is for testing purpose only. I will be calling package function instead to get return value. And this is yet to be tried in any of these scenarios. If anyone could address that too with example, that would be great!
Thanks in advance.
You need to assign the result of sqlplus to a variable which must be displayed within ssh so that the result is passed to variable retVal. Try the following code:
retVal=$(ssh $v_server_user#$v_server_name ssh_v_schema_name=$v_schema_name ssh_v_schema_pwd=$v_schema_pwd ssh_execute_command=\""$execute_command"\" 'bash -s' <<SSHSQLTEXT
sqlresult=`sqlplus -S $ssh_v_schema_name/$ssh_v_schema_pwd <<EOF
SET ECHO OFF
SET HEADING OFF
SET FEEDBACK OFF
SELECT SYSDATE FROM dual;
exit
EOF`
echo $sqlresult
SSHSQLTEXT
)
echo "return value 2: "$retVal
If you execute the above block of codes, you will have the sysdate as result in $retval

using SQL query on unix [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Select columns into local variable from sql script using shell script
im trying to write a unix script that will retrieve a parameter using sql query and run a script afterwards with this parameter.
for the time being, im just tryin to make it echo the retrieved parameter.
the sql query that works fine on toad (oracle 8) is :
select billcycle from bc_run
where billcycle not in (50,16)
and control_group_ind is null
and billseqno=6043
the above query give a number.
now the script i wrote is:
#!/bin/bash
echo "this script will print the billcycle date"
v_bc=`sqlplus -s /#bscsprod <<EOF
select billcycle from bc_run
where billcycle not in (50,16)
and control_group_ind is null
and billseqno=6043`
echo "billcycle number is $v_bc"
the result when i run the file is
billcycle number is
with no number that follows.
any ideas what's wrong ? maybe the syntax for connecting to the sql server ?
thanks
Assaf.
The duplicate question APC linked to shows a working example, but to clarify you have two problems. The first is non-fatal and is just that you don't have EOF, as Rembunator pointed out (though it's in the wrong place in that answer).
More importantly though you don't have a terminating ; in your query, so SQL*Plus won't execute it - it just exits with no output.
If you typed your original query in as the SQL*Plus command prompt it would leave you at a further prompt waiting for input, and then go back to a normal prompt if you just hit return again, without actually executing the query:
SQL> select billcycle from bc_run
2 where billcycle not in (50,16)
3 and control_group_ind is null
4 and billseqno=6043
5
SQL>
You also probably want at least some formatting of the output. So this should work:
v_bc=`sqlplus -s /#bscsprod <<EOF
set pagesize 0
select billcycle from bc_run
where billcycle not in (50,16)
and control_group_ind is null
and billseqno=6043;
EOF`
I think you should end with EOF as well:
v_bc=`sqlplus -s /#bscsprod <<EOF
select billcycle from bc_run
where billcycle not in (50,16)
and control_group_ind is null
and billseqno=6043
EOF`
Edited: Oops, as corrected by Alex Poole.

Resources