How do you access the command prompt using Aspen SQLPlus?
I have tried using Host Dir, but does not seem to work.
You need to use the SYSTEM command. This is covered quite well within the Aspen SQLPlus help menu.
E.g.
SYSTEM ('DIR');
SYSTEM ('DIR C:\WINDOWS\');
SYSTEM ('ROBOCOPY C:\SCRATCH\ C:\USERS\JOHN\DESKTOP\ TEST.TXT');
SYSTEM ('HOSTNAME');
SYSTEM ('WHOAMI');
Will print the results to screen.
Alternatively, you can format the results as a table:
select line, linenum from SYSTEM ('DIR');
It is also possible to interact with the results, within a for loop:
for (select linenum ilinenum, line iline from SYSTEM ('DIR'))
do
write ilinenum || chr(9) || iline;
end
A few things to note:
No interaction is possible, e.g. if you attempt to COPY a file and are prompted if you want to overwrite Y/N, this will get stuck.
The IP21 Service Account will always execute the command, regardless of the user who executes the SQLPlus query.
If you wish to execute multiple commands, you will need to load a batch file
Related
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.
I am trying to dump PostgreSQL tables using a COPY statement. I am using COPY instead of pg_dump because I need to perform a transformation on one of the columns as it comes out.
The statement I would like to execute is essentially this
COPY ( SELECT 'punt' ) TO PROGRAM '7z a -si C:/Users/Public/Documents/punt';
but I am getting the generic error
ERROR: program "7z a -si C:/Users/Public/Documents/punt" failed
DETAIL: child process exited with exit code 1
I am trying to pass the COPY output through 7zip similar to the fourth example in the COPY documentation in order to compress the output as the database is about 130 GB and I'm ideally working with SSDs. The following command works fine:
COPY ( SELECT 'punt' ) TO 'C:/Users/Public/Documents/punt';
with result COPY 1. I have executed the following command on the psql prompt and it also works which makes me fairly confident about syntax and permissions:
\! echo 'punt' | 7z a -si C:/Users/Public/Documents/punt
Am I missing something about the cmd pipeline or the 7zip executable permissions?
EDIT: Postgres version is 9.3.3
I'm still getting the same error after changing the dir permissions to NETWORK SERVICE based on Craig Ringer's answer. This, however, did not fix the problem and the error is identical. Even after changing the target directory's permissions giving full control to Everyone, I still got the same error. I also tried changing the permission on the 7zip executable and the 7zip Program Files Directory to no avail.
In experimentation, I ran the following, taking the input from copy out of the equation:
COPY ( select '1' ) TO PROGRAM 'echo punt | 7z a -si C:/Users/Public/Documents/punt';
and curiously got the failure message, but instead with exit code 255, which for 7zip has the meaning "User stopped the process". Can't seem to find a reason for this myself.
It'll be a permissions issue.
The PostgreSQL server runs as NETWORKSERVICE for 9.2 and above, or user postgres for 9.1 and below, by default. COPY runs server-side as the user PostgreSQL its self runs as.
Neither of these are likely to have the right to write to C:\Users\Public\Documents.
You'll need to grant the PostgreSQL service user the right to write there using the Windows security properties dialog, or choose another location it can write to.
It works with \! because psql is running as your user, which will have permissions to write there, and \! runs the command client-side as the user running psql.
Strikethrough the 7zip bit in my edit, the 255 error code is actually from cmd not finding the 7zip exe. I plopped 7zip.exe on C:/ (couldn't figure out escaping the space in Program Files) and ran
COPY ( SELECT 'punt' ) TO PROGRAM 'C:/7z a -si C:/Users/Public/Documents/punt';
and this worked. I'm guessing the NETWORKSERVICE user doesn't have the path environment variable loaded, but I'm not sure about that.
I set the permissions on C:/Users/Public/Documents back to its default and the COPY ... TO PROGRAM still worked so file permission wasn't an issue in this specific case. I would still look to Craig Ringer's suggestion first if I encountered a problem like this again.
CMD doesn't recognize a path with spaces.
COPY FROM PROGRAM doesn't have access to PATH variables.
Just wrap your PROGRAM_NAME like RESOURCE_NAME in double apostrophes and you are done:
COPY ( SELECT 'punt' ) TO PROGRAM '"C:/Program Files/bla/bla/7z.exe" a -si "C:/Users/Public/Documents/punt"';
Background information:
I am trying to set up a batch job for syncing stored procedures between different sql servers. I did export all stored procedures into seperate .sql files into my folder. Whenever I want to create a new stored procedure or change it for those multiple servers, I test it on 1 server until I got it the way i want it. After that I export it into my folder. To then deploy it to the other servers, I simply execute a batch - that's it.
I've almost figured out my batch the way i want. The only problematic thing is, that sqlcmd seems not to like the standard batch separator 'GO' ('Incorrect syntax near 'GO'.'). So i've changed my default batch separator to 'RUN', replaced each 'GO' command with 'RUN' in my .sql files and added -c RUN to my sqlcmd command.
However it then tells me 'Incorrect syntax near 'RUN'.'.
For testing purposes I just tried it out with 1 shrinked sql file, looking like this:
USE [MyDatabase]
GO
Even that did not work. How can I make it work?
Try leaving out GO or RUN from these scripts. You can change database context without them.
You should be fine to do something like this:
USE MyDatabase;
--First query
USE MyOtherDatabase;
--Second query
I'm trying to use sql*plus to control a small Windows command script.
Basically, I want to execute some PL/SQL (perhaps select from a view or table or execute a function) which shows me the status of some rows in the database, and then depending upon the state of the rows, perform some Windows commands.
My problem is how to get the results back into the command script.
sqlplus user/password#server #script.sql
IF <CONDITIONAL HERE BASED on script.sql results> GOTO :runprocess
REM log and email that process had to be skipped
EXIT
:runprocess
REM run various Windows service commands
I'd probably write the script (or the conditional, depending on the requirements) from the called script.sql itself.
For example, the following script.sql creates a .bat file windows_commands.bat:
set feedback off
set echo off
set trimspool on
set termout off
set serveroutput on size 100000 format wrapped
set lines 500
set pages 0
-- create the bat file to be executed later:
spool windows_commands.bat
declare
c number;
begin
select count(*) into c from dual;
-- depending on a conditional, write the stuff to be executed into the
-- bat file (windows_commands.bat)
if c = 1 then
dbms_output.put_line('#echo everthing ok with dual');
else
dbms_output.put_line('#echo something terribly wrong with dual');
end if;
end;
/
spool off
exit
You can then call script.sql from yet another .bat file like so:
#rem create oracle session, call script.sql
sqlplus %user%/%password%#%db% #script.sql
#rem script.sql has created windows_commands.bat.
#rem call this newly created bat file:
call windows_commands.bat
This is what I ended up using.
My .cmd script:
#ECHO OFF
ECHO Checking Oracle...
for /f %%i in ('sqlplus -s user/password#database #script.sql') do #set count=%%i
echo %count%
IF %count% GTR 0 GOTO :skipped
GOTO :runprocess
Where script.sql:
SELECT COUNT(*)
FROM table
WHERE criteria = 1;
exit
I would strongly encourage you to not use .bat files. You've got lots of other alternatives: C/C++ or VB, Windows scripting or Powershell, or even free downloads like Perl or Bash.
But here's one example of returning error codes in .bat files:
http://www.dbforums.com/oracle/1044496-sqlplus-return-value-help.html
But please do look at some of the links I gave above. Avoiding .bat files will make it easier for you, and make it easier to maintain in the future.
IMHO ...
I do something like this by creating a .bat file which does the windows stuff and calling sql scripts as needed. Use SQL to spool your results to a text file which you can read.
...dos commands here
sqlplus /nolog #C:\Dump\DropRecreateUsers.sql
sqlplus /nolog #C:\Dump\Cleanup.sql
...dos commands
In the sql use this command spool C:\yourResults.txt or for more sophisticated usages create a procedure, which, when called, writes the results to a text file using UTL_FILE
I encourage you to take a look at the two scripts included in the Oracle XE for backup and restore. These scripts have taught me a lot how to handle batch-scripting and Oracle on the Windows platform.
C:\oraclexe\app\oracle\product\11.2.0\server\bin\Backup.bat
C:\oraclexe\app\oracle\product\11.2.0\server\bin\Restore.bat
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> #f:\testa.txt
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