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

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.

Related

How to format oracle connection string and output query to file

I am trying to connect to a oracle database, query it, and send results to a txt file. When I run my statement, this shows in the .txt file:
In reality, it should be values from my sql script.
Here is the string i am running:
sql_file1=Cb.sql
sqlplus -s "username/pwd#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=my_host)(Port=1521))(CONNECT_DATA=(SERVICE_NAME=my_ser_name))))" #sql/$sql_file1 > /home/path/to/my/files/'cb.txt'
Any reasons as to why my 'cb.txt' file shows the screenshot from above instead of any date from the query inside my sql file?
You have extra ) in your connection string:
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=my_host)(Port=1521))(CONNECT_DATA=(SERVICE_NAME=my_ser_name))))
should be
sqlplus -s "username/pwd#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=my_host)(Port=1521))(CONNECT_DATA=(SERVICE_NAME=my_ser_name)))" #sql/$sql_file1 > /home/path/to/my/files/cb.txt
But even easier to use EZConnect string:
sqlplus -s "username/pwd#//my_host:1521/my_ser_name" #sql/$sql_file1

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

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.

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.

sqlplus query with comment giving duplicate rows

Updating my question:
When I run this query from unix using sqplus it gives me duplicate outputs
Query:
select sysdate from dual
/
/*comment*/
EXIT
Output
SQL> #tt.sql
12-AUG-16
12-AUG-16
Here is what is happening.
The first two lines (including the /) form a complete SQL statement. SQLPlus executes it and displays the first line.
Then /*comment*/ is OUTSIDE the SQL statement. So it is interpreted by SQLPlus, not as a SQL comment.
The point is, comments in the SQLPlus scripting language have a different syntax; they are lines that begin with REM[ARK]. /*comment*/ is NOT a comment in SQLPlus.
Instead, in SQLPlus, a slash / as the first character on a new line means repeat the last SQL command (if after that you had SQLPlus commands, like DESCRIBE or COLUMN, those are ignored). Everything AFTER the slash is ignored. To convince yourself of this, try again, but with the comment line changed to /*comment* (delete the second slash). You will see the same result.
Then you have the command EXIT, but since it is NOT followed by a slash, it is not seen as a completed command. If I copy and paste your code in my SQLPlus window, I get the screenshot below. However, if at this point you press ENTER (or if this was in a sql script and not copied and pasted from a text editor), the SQLPlus window would shut down.
Hope this helps!
SQL> select sysdate from dual
2 /
SYSDATE
----------
2016-08-12
1 row selected.
Elapsed: 00:00:00.00
SQL> /*comment*/
SYSDATE
----------
2016-08-12
1 row selected.
Elapsed: 00:00:00.01
SQL> EXIT

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