I'm trying to create a batch file to run a sql query (which then spools the result).
However, at the moment nothing happens, I just get usage info about sqlplus in the cmd window. Here is my batch code:
SQLPLUS login/password#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=<url>)(Port=<port>))(CONNECT_DATA=(SID=<sid>)))#C:\Users\Documents\SQL\test2.sql
pause
and here is my test2.sql file:
spool C:\Users\Documents\Testing.csv
select *
from test;
spool off;
exit;
Please help - what am I doing wrong? (I'm very new to this so please answer/ask/ridicule in simple terms so I can understand)
It's something obvious you're doing wrong. You need a space between the end of the connect string and the # with the script file name:
SQLPLUS login/password#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=<url>)(Port=<port>))(CONNECT_DATA=(SID=<sid>))) #C:\Users\Documents\SQL\test2.sql
The <url> reference is odd here; hopefully that is actually hostname, fully-qualified hostname (that can be resolved), or an IP addrss.
However, I'd suggest you use a TNS alias so you can shorten the command line, putting all that information in a tnsnames.ora file instead; or if you know the service name (which might be the same as the SID) use the easy connect syntax:
SQLPLUS -l -s login/password#//<hostname>:<port>/<service_name> #C:\Users\Documents\SQL\test2.sql
I've also thrown in the -s flag to suppress the banner, and the -l flag so it stops if the credentials or connect string are wrong. Your original ersion would have tried to use the script contents to log in after the initial failure, producing even more confusing output.
Related
A shell script with a database connection using sqlplus contains this line:
sqlplus username/password#DBNAME<<EOF>tmp.
(here there is a select sql query)
I know <<EOF indicates the start of the command. I have the below doubts in the >tmp part.
1)Does it indicate storing into a file?
2) If yes will it put the results of the SQL query alone into the tmp file or the query and the results both.
Could you please clear me on this one?
<<EOF is known as "heredocs". It means that from the next line in the script, up to a line that says "EOF", will be read in by the shell, and offered to the command on standard input.
In your case, the sqlplus command is being fed the SQL query as if it came from standard input. Then, the output of sqlplus is being saved to the file called tmp.
The input and output are separate. However, sqlplus as a command has a habit of repeating its input to the output, unless instructed otherwise with SET ECHO OFF.
I need to update a table with some where conditon. If update fails then I need to insert the same. I am using here document from a shell script to run sqlplus, please help me to find the way so I can insert in case of faliur of update.
Redirect the output to a temporary file and don't forget to include stderr as well. Then you can parse the output and look for characteristics. In your SQL you can also do a
select "SUCCESS" from dual;
at the end, the shell script could look for.
sqlplus user#db #my_sqlfile >output 2>&1
grep "SUCCESS" output
sqlplus also usually writes in the output something like
N records updated.
So you can also check if there are as many updates as you expect if you need this.
Just be sure to set the options in your sql file appropriately because this affects what sqlplus will spill out.
set term ...
I have the following batch script:
sqlplus ms/ms#orcl < drop.sql
sqlplus ms/ms#orcl < create.1.0.sql
This works fine when I double click on the bat file in Windows Explorer and run it.
But when I type the command name from the DOS prompt I get an error:
C:\>create.bat
C:\>sqlplus ms/ms#orcl 0<drop.sql
The handle is invalid.
C:\>sqlplus ms/ms#orcl 0<create.1.0.sql
The handle is invalid
Any ideas?
Update: Made the change to use # instead of <. This gets around the error but now the script only executes the first file and then leaves you at the SQL> prompt. To get the second file to execute you have to type exit at the prompt, then the second file runs. Not sure how to get both files to execute. ??
If you want SQL*PLUS to execute a script, a better way than command-line redirection is the # syntax:
sqlplus ms/ms#orcl #drop.sql
sqlplus ms/ms#orcl #create.1.0.sql
Also read up on the ## syntax, which you can use to execute a .sql script from another .sql script in the same directory.
SQL> help #
SQL> help ##
Made the change to use # instead of <.
This gets around the error but now the
script only executes the first file
and then leaves you at the SQL>
prompt. To get the second file to
execute you have to type exit at the
prompt, then the second file runs. Not
sure how to get both files to execute.
??
I ended up writing a python script to run sql plus and then exit it to get around this issue. I have yet to find any way around that limitation. Although you would only have to deal with the issue once if you use ## as was suggested. You would just have to run the second script from the first script.
I have written the sql by name cashload.txt on unix box and kept it on the following location on unix box:
exit |sqlplus -s batch/password#SW_TEST #/soft/checkfree/AccurateBXG/scripts/cashload.txt
In the cashload.txt the below code is written:
spool /Detail/reports/inner/SW/Rep_OIbyAccount_$DATE_FILE.csv
select accountnumber||','||accountname||','||X from HSBC_Cash_OIbyAccount_v;
spool off
But it is not spooling the result set on the above mentioned path.However,when I am giving the path where the script is kept,It is spooling at that location.I don't understand why?It is spooling at the below path where the cashload.txt(sql script) is kept:
**spool /soft/checkfree/AccurateNXG/scripts/Rep_OIbyAccount.csv**
select accountnumber||','||accountname||','||X from HSBC_Cash_OIbyAccount_v;
spool off
Please look into the above query and help me out.
Thanks in advance!!!
If I understand this correctly, DATE_FILE is a shell variable that you want to substitute into the spool file name. This might be part or all of your problem. I don't think you can reference this directly from SQLPlus. You would need to pass that in as a parameter to the script then reference it as a SQLPlus substitution variable.
So the command line would be:
sqlplus -s batch/password#SW_TEST #/soft/checkfree/AccurateBXG/scripts/cashload.txt $DATE_FILE
And the spool command in the script would be:
spool /Detail/reports/inner/SW/Rep_OIbyAccount_&1..csv
(The extra period is necessary because it serves as a terminator to the substition variable name.)
Almost certainly it is a file permissions problem. Remember that when we interact with the OS from inside the database we are using the oracle account, not the account we connected as.
So does the oracle account have write permissions on /Detail/reports/inner ?
Can you echo the value of "/Detail/reports/inner/SW/Rep_OIbyAccount_$DATE_FILE.csv" ?
Only reason I can think of are
a) The above location is not a valid path
b) You do not have permissions to write to that location.
Do you get an error in the first case, or does nothing happen at all ?
Does running without the silent (-s) option give you any more detail?
The path mentioned by you has a $ symbol which is causing the problem. To avoid that just give the path and file name in " ". That should solve the problem:
SPOOL "/Detail/reports/inner/SW/Rep_OIbyAccount_$DATE_FILE.csv "
Maybe you can try the following to see if it generats the desired output. It will put in the directory which you are currently in.
set termout off
set echo off
set linesize 140
set feedback off
set pagesize 0
spool DATE_FILE.csv
select accountnumber
||','
||accountname
||','
|| X
from HSBC_Cash_OIbyAccount_v;
spool off
ed DATE_FILE.csv
I'm running Oracle 11g on Linux and I'm trying to run a script which will create my database. This script runs fine on windows, but when I test it on Linux, I get the following error:
SP2-0556: Invalid File Name
The problem may be that the path to the file name has a space in it. I'm going to simplify the problem down to one of the many commands I run in the file to make it simple. The sample command I'm trying to run looks like this:
sqlplus [uname]/[pw] #'../database/My Schema/create_sequence.sql'
the create_sequence.sql file has two simple create sequence commands that run fine by themselves. I strongly suspect it is due to the white space because when I change the directory name from My Schema to MySchema and alter the above sqlplus command accordingly, the script runs fine.
Like I said, this script works in windows with the spaces, but not in Linux. I suspect spaces may not be supported, but I was wondering if anyone knew any different or it there is a work-around?
side note: running a command like:
more ../database/My\ Schema/create_sequence.sql
or
more "../database/My Schema/create_sequence.sql"
prints the contents of the file to the console as you would expect. So, I think this is sqlplus (and linux) specific.
I connected to one of my Linux boxes and was pretty easily able to reproduce this issue. There doesn't seem to be any way that I can find to execute the file with the '#' option from the command line so I think you're left with the following options for work arounds:
Rename the My Schema directory to no longer have a space in it (as well as updating all other scripts that reference it
Execute the file from the directory in which it resides (I confirmed that this works, see below)
Send the file into sqlplus via stdin (see below)
You should also file a report with Oracle support as there may be a simple fix that they can provide.
Example Commands:
From Directory
cd ../database/My\ Schema
sqlplus [uname]/[pw] #create_sequence.sql
Via stdin
sqlplus [uname]/[pw] < ../database/My\ Schema/create_sequence.sql
Well, if this is a Linux issue (see my comment on your question - it works fine on Solaris), you may have to try something along the lines of:
sqlplus [uname]/[pw] < '../database/My Schema/create_sequence.sql'
You run into problems if you're trying to pass parameters to your sql script, however...
EDIT: There seems to be a Metalink issue raised for a very similar problem: "Bug 7150873 SQL scripts with filename containing spaces results in SP2-0556". It is listed as affecting 10.2.0.4 and 11.1. It is supposedly fixed in 10.2.0.5 and 11.2, neither which are available yet. It does say it's a generic issue affecting most/all platforms, so I don't know if this is your problem or not.
The specific text of the issue: "The SQLPLUS START command fails to execute SQL scripts which have a space in the filename."
Just for grins, what happens if you do the following:
sqlplus [uname]/[pw]
start '../database/My Schema/create_sequence.sql'
EDIT2: I don't know if modifying your scripts wholesale is feasible or not, but a workaround might be:
cp '../database/My Schema/file2run.sql' ./temp.sql
sqlplus [uname]/[pw] #temp.sql
rm ./temp.sql
You would need to wrap each sqlplus call this way. Another option would be to create a shell script, say with a name of mysqlplus.sh:
#!/bin/sh
cp $2 ./temp$$
sqlplus $1 #$2
rm ./temp$$
Then modify your build scripts thus:
mysqlplus.sh [uname]/[pw] '../database/My Schema/create_sequence.sql'
According to this thread on the OTN site, SP2-0556 can be caused by invalid white space characters in the file that is being executed. Likely the Linux version of SQL-Plus doesn't know how to deal with Windows newline character(s). Try deleting the existing file and recreating it with your desired commands (you said there are only 2 DDL commands so it should be easy).
If you put quotes around path, it works:
SQL > START "C:\Documents and Settings\Administrator\demobuild.sql"
This does not work:
SQL > START C:\Documents and Settings\Administrator\demobuild.sql
have you tried escaping the white space?
Try:
sqlplus [uname]/[pw] #'../database/My\ Schema/create_sequence.sql'
If you're working with this under linux you can escape the space with a '\' character like such:
sqlplus [uname]/[pw] #../database/My\ Schema/create_sequence.sql
I know it's an old question but I just ran into the same situation and after a lot of tries I made it work and I want to share my solution, it was simply put the path into quotes like this:
#"C:/Users/john/AppData/Roaming/SQL Developer/test.sql";