SQL*Plus ## behaviour with spaces in the parent script path - oracle

I have to
Connect
Call sql-script
Exit sqlplus
So, I've created a sql-script run.sql:
set def on
WHENEVER SQLERROR EXIT ROLLBACK
conn &2
#"&1";
exit;
For example, I have some sql-scripts in a folder "c:\folder with spaces\":
a) install.sql with contents:
prompt Hello
##a.sql
##b.sql
b) and of course I have a.sql and b.sql files in the folder with some actions.
So, I try to run my script:
sqlplus /nolog #"Path_to_Run\run.sql" \"c:\folder with spaces\install.sql\" user/pass#server
And I got an output:
Hello
SP2-0310: unable to open file "c:\folder.sql"
So, it can open install.sql, but cannot open ##a.sql. He tries to run such script:
#c:\folder with spaces\a.sql
But how can I place quotes here? He should run the script a.sql inside the folder "c:\folder with spaces\".

You could split your parameters so that run.sql contains
set def on
WHENEVER SQLERROR EXIT ROLLBACK
conn &2
host cd "#3"
#"&1";
exit;
And invoke it with
sqlplus /nolog #"Path_to_Run\run.sql" \"c:\folder with spaces\" install.sql user/pass#server
Note that it might need some tuning, it does not work on my computer because of cygwin messing with its own cd.

Thanks to Alex Poole, the answer is in documentation
SP2-0310 Error when Calling a SQL Script in Another Script using ## and the Path to the Parent Script Contains Spaces (Doc ID 745780.1)
And there are three solutions:
Use the 8dot3 notation. E.g. Use PROGRA~1 instead of "Program Files".
Avoid saving the sql scripts on a path containing spaces in the folder names.
cd to the directory containing the script instead of providing the full path when invoking the script in SQL*Plus.
First method doesn't work for me in Windows 7 (there are a lot of work to set up 8dot3 in Win7). I get:
>cd c:\folder~1
The system cannot find the path specified.
Second method doesn't work for me too, I cannot operate these folders. I have to use them as is.
And the third method works fine (but in another way than in the previous message):
cd "c:\folder with spaces"
sqlplus /nolog #c:\run\run.sql install.sql user/pass#server
So, you have to change dir before sqlplus, host cd doesn't work.
Thank you, guys.

Related

What is the difference between !call and call in windows batch

There are 2 files: file1.bat, file2.cmd
file1.bat invokes file2.cmd through command:
db2cmd -i -c -w db2 !call file2 parm1 parm2
This command opens a DB2 command window at the same window and invokes file2.cmd
However, what I can't understand is the function of '!' in front of 'call'.
file2.cmd has below features:
1. DB connection: db2 connect to dbname user username using psw
2. File open: for /F "delims=;" %%i in (input.txt) do (do something)
If passing the incorrect parameters,
---------With 'call' in the file1 command, error shows:
SQL1024N A database connection does not exist. SQLSTATE=08003
---------With '!call' in the file1 command, error shows:
SQL1001N "xxx" is not a valid database name. SQLSTATE=2E000
The system cannot find the file \input.txt.
DB20000I The TERMINATE command completed successfully
So, it looks like 'call' invokes another file and break with high level error message once one of the command fail;
While '!call' invokes another file and continue to run all the commands insides even though there are error, then displays all the error messages of all the failure.
Can someone advise the difference between 'call' and '!call'?
Ok, so simply put, there is no function !call in batch/cmdline. So db2cmd.exe being a commandline processor itself, requires you to use system commands with a preceding !
So though you have a batch file that runs the command with parameters, effectively this is what happens. You are starting db2cmd from this cmd, it then requires you to call another batchfile, but seeing as we are not within the shell of cmd anymore, but rather inside of db2cmd you're then required to tell db2cmd that it is a system command you're executing by doing !call
You can test it by doing on its own db2cmd where you will get to a db2=> prompt and then try and use call vs !call from there.
As for your error message:
SQL1001N "xxx" is not a valid database name. SQLSTATE=2E000
The system cannot find the file \input.txt.
DB20000I The TERMINATE command completed successfully
Try and add a path to the input.txt file
for /F "delims=;" %%i in (C:\somepath\input.txt) do (
something
)
or place input.txt in your working dir.
There is an easier way to handle running Db2 CLP commands inside a Windows batch file.
Db2 on Windows requires that Db2 CLP commands run inside a db2cmd.exe window.
(otherwise a db2 command in a normal cmd.exe window may fail with an error).
The db2cmd.exe is shipped with the Db2 Client for windows.
The solution is to arrange that the script auto-detects whether it is running
inside db2cmd.exe , and if not then run itself under db2cmd.
With this approach the calling script (if there is one)
can simply contain "call file2.bat par1 parm2" and can be executed by the normal CMD.EXE,
while the "file2.bat" can then contain:
#set db2cmd="C:\Program Files\IBM\SQLLIB\BIN\db2cmd.exe"
#if "%DB2CLP%"=="" %db2cmd% /w /c /i "%0" %* && #goto :EOF
#rem If db2cmd.exe is on the system PATH then you can omit the set db2cmd line.
db2 connect to dbname user username using psw
...rest of script...
...you can use db2 CLP commands directly
The first line sets a variable to contain the fully qualified pathname to the db2cmd.exe executable. This is the default path so you may need to change the pathname to match your environment, and you can omit this if you are certain that db2cmd.exe will always be on the system path.
The second line tests if the script is running under db2cmd.exe (in which case the DB2CLP environment
variable will be set). If the script is not running under db2cmd.exe then the script runs itself
under db2cmd.exe passing on the same command-line parameters. If the script is already running under db2cmd.exe then continue to the next line.

Cannot execute .sql with sqlplus (windows)

I have finally connected to sqlplus under windows with command:-
sqlplus -S "dbname/dbpassword#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=)(Port=1521))(CONNECT_DATA=(SID=SID_OF_DB)))"
(Can't connect with configuration file but command line works well for me.)
But I'm not able to execute sql file along with the command.
It is definitely possible to execute .sql file with directive << under linux, but how do I execute in windows?
I'm using sqlplus to generate csv within batch file and importing to mysql. Presently using login.sql as alternate.
You can connect and execute using the '#' followed by your file name as mentioned by Chris. You can use it as follows.
sqlplus -S user/password#SID_OF_DB #oracle.sql
You should be able to run a SQL file by adding #filename onto the end of your command to open sqlplus. If the file is not in your current working directory you will need to include the path. Also if there are any spaces in the name or path then enclose the whole path within double quotes.
Some more info about the command line options can be found here.

Check existence of directory on local machine during ftp session

I am copying a large number of files during an ftp session from a remote host to my local machine. I need to save the files in a local directory tree. My problem is that a particular directory may not exist before the session. The way I have handled this in the past is to do set up my script by first creating the directory tree and not even worrying if the directory exists and then from within the same batch file (I create the batch file using Python) I start my session and use lcd to change to the correct directory
md c:\123
md c:\234
md c:\234\2009
loginname
password
cd remotedirectory
lcd c:\123
get somefile.txt
So all of the above is written out to one batch file and I start it to run. If the directory exists when I try to create it then I see a message in the terminal window that the directory exists and since nothing bad happens I have not worried about it.
What I would really like to do is check the existence of the local directory when I am ready to move to that directory and if it does not exist it gets created but I have not found out how to do this without closing the session and restarting it so I go back to the shell.
Is there a way to do this during the ftp session while maintaining the connection with the host?
You can use the ! command prefix to execute CMD MD command in order to make sure a local directory is already exist. e.g.:
! md "c:\my data\download" will create c:\data\download directory if it's not yet exist (and assuming you have the required permission). If it's already exist, it'll just display a harmless error. You can also use ! md "c:\my data\download" > nul to omit the error message. Or perform other commands.
Basically, everything after the ! ftp command prefix, will be passed to CMD.EXE as cmd /c {your command(s)}. If ! is used alone, it'll escape to CMD session prompt and wait for user input. The CMD's EXIT command will close the CMD session and return to the FTP prompt.

Execute windows cmd command on all files in directory

Very simply, I want to execute a command on every file in a directory, one at a time, and log the output of that command.
I wrote the following batch script:
pushd C:\Program Files\Log Parser 2.2
for %%x in (C:\templogs\3\C\IISLogFiles\W3SVC3\deduped*.log) do (
LogParser "SELECT * INTO weblog FROM %%~dpnx" -i:W3C -o:SQL -server:localhost -database:testdb -driver:"SQL Server" -createTable:OFF >> input.out
)
popd
When I execute it in the command prompt, all it does it copy paste those commands exactly as is. Nothing executes. any idea?
The only situation when that would be the case is when:
dir C:\templogs\3\C\IISLogFiles\W3SVC3\deduped*.log
... would come back blank. Could you please double check that this path actually contains files you want to process...?
I've tried it several ways and always got expected result (LogParser is not recognized in my case), unless I've tried on the path that did not existed on my system...
How about just executing LogParser as:
LogParser "SELECT * INTO weblog FROM C:\templogs\3\C\IISLogFiles\W3SVC3\deduped*.log" -i:W3C -o:SQL -server:localhost -database:testdb -driver:"SQL Server" -createTable:OFF

SQL Plus change current directory

How does one change the current directory in SQL Plus under windows.
I am trying to write a script with several "# filename" commands.
I know that one can open a script with the File --> Open command, which will change the current directory, but I am looking for a way to do this automatically unattended.
Resolution
Based on Plasmer's response, I set the SQLPATH environment variable in Windows, and got something that's good enough for me. I did not try to set it with the HOST command (I doubt that it will work).
Pourquoi Litytestdata's answer is a good one, but will not work for me (the directories are too far apart). And of course Guy's answer that it cannot be done is also correct. I will vote these two up, and accept Plasmer's answer.
Here is what I do.
Define a variable to help you out:
define dir=C:\MySYSTEM\PTR190\Tests\Test1
#&dir\myTest1.sql
You can't cd in SQL*Plus (you can cd using the host command, but since it is a child process, the setting won't persist in your parent process).
I don't think that you can change the directory in SQL*Plus.
Instead of changing directory, you can use ##filename, which reads in another script whose location is relative to the directory the current script is running in. For example, if you have two scripts
C:\Foo\Bar\script1.sql
C:\Foo\Bar\Baz\script2.sql
then script1.sql can run script2.sql if it contains the line
##Baz\script2.sql
See this for more info about ##.
Could you use the SQLPATH environment variable to tell sqlplus where to look for the scripts you are trying to run? I believe you could use HOST to set SQLPATH in the script too.
There could potentially be problems if two scripts have the same name and both directories are in the SQLPATH.
I don't think you can!
/home/export/user1 $ sqlplus /
> #script1.sql
> HOST CD /home/export/user2
> #script2.sql
script2.sql has to be in /home/export/user1.
You either use the full path, or exit the script and start sqlplus again from the right directory.
#!/bin/bash
oraenv .
cd /home/export/user1
sqlplus / #script1.sql
cd /home/export/user2
sqlplus / #script2.sql
(something like that - doing this from memory!)
With Oracle's new SQLcl there is a cd command now and accompanying pwd.
SQLcl can be downloaded here: http://www.oracle.com/technetwork/developer-tools/sqlcl/overview/index.html
Here's a quick example:
SQL>pwd
/Users/klrice/
NOT_SAFE>!ls *.sql
db_awr.sql emp.sql img.sql jeff.sql orclcode.sql test.sql
db_info.sql fn.sql iot.sql login.sql rmoug.sql
SQL>cd sql
SQL>!ls *.sql
003.sql demo_worksheet_name.sql poll_so_stats.sql
1.sql dual.sql print_updates.sql
SQL>
Have you tried creating a windows shortcut for sql plus and set the working directory?
I think that the SQLPATH environment variable is the best way for this - if you have multiple paths, enter them separated by semi-colons (;). Keep in mind that if there are script files named the same in among the directories, the first one encountered (by order the paths are entered) will be executed, the second one will be ignored.
Years later i had the same problem. My solution is the creation of a temporary batchfile and another instance of sqlplus:
In first SQL-Script:
:
set echo off
spool sqlsub_tmp.bat
prompt cd /D D:\some\dir
prompt sqlplus user/passwd#tnsname #second_script.sql
spool off
host sqlsub_tmp.bat
host del sqlsub_tmp.bat
:
Note that "second_script.sql" needs an "exit" statement at end if you want to return to the first one..
for me shelling-out does the job because it gives you possibility to run [a|any] command on the shell:
http://www.dba-oracle.com/t_display_current_directory_sqlplus.htm
in short see the current directory:
!pwd
change it
!cd /path/you/want

Resources