I am using Command Prompt to run SQL Scripts. One of the script requires a file name which is read from a settings file (file_name=ABC) by CMD and feed to the script like so
sqlplus #"Script_Run" %file_name%
Inside the script the input is read in the line:
UTL_FILE.FOPEN('DIR','&1.ext','R');
Now when I run the bat file,
the substitution happening is:
old: "&1.ext"
new: "ABCext"
the script returns "Invalid File Operation" error.
But when I change the script line to:
UTL_FILE.FOPEN('DIR','&1..ext','R');
it works. Why does the sql script here require two dots ?
improved formatting
As documented in the SQL*PlusĀ® User's Guide and Reference, the period is used to concatenate the value of a substitution variable with other characters:
If you wish to append characters immediately after a substitution variable, use a period to separate the variable from the character. For example:
SELECT SALARY FROM EMP_DETAILS_VIEW WHERE EMPLOYEE_ID='&X.5';
Enter value for X: 20
is interpreted as
SELECT SALARY FROM EMP_DETAILS_VIEW WHERE EMPLOYEE_ID='205';
Related
I am working on a unix machine and the only way to execute oracle sql commands is through a unix script we grant access like this :
#! /user/bin/ksh
User = 'PATH' # I can't read the file in this path
sqlplus $user << word # I don't know what it is used for
And then I start writing sql commands then execute the script through cmd
My question is:
Do I have any way to login to sqlplus directly through the info above through cmd
I tried to use this command to log in directly to SQL*Plus:
sqlplus $user << word # I don't know what it is used for
But it prompted username: # which I don't know
User = 'PATH' # I can't read the file in this path
There is no file to read. You are assigning the string literal 'PATH' to the environment variable "User". You could just as well say "User = 'FUBAR'"
sqlplus $user << word # I don't know what it is used for
It is telling the OS to launch the executable 'sqlplus', pass it the value of the environment variable "$user", then redirect other input from the next lines of the script until it comes to the string literal 'word'. This is call 'input redirection, and the commands between this line and the line beginning with the word 'word' are sometimes referred to as "a 'here' document". Using the string literal 'word' to terminate it is wierd and misleading at best. Most people use some variation of 'EOF' for this purpose.
I don't know what it is expected to be used for either. In *nix, environment variables (as are file names) are case sensitive. So this variable , "user" is not the same variable, "User" as you set in the previous line.
And then i start writing sql commands then execute the script through
cmd
I'm not sure what you mean by this. Are you saying that at this point, your script has sql commands intended to be processed by sqlplus? As indicated by your use of input redirection?
But it prompted username : # which I don't know
Well, in spite of all the other issues, if you don't know the username and password, you will never be able to connect to the database.
If your unix box is setup correctly the variable PATH should include /usr/local/bin you can test by typing in the command echo $PATH.
if its setup, the source in the oracle file oraenv like so
. oraenv
Note there should be a space between the period a the word oraenv. By doing this it should append the directories $ORACLE_HOME:$ORACLE_HOME/bin to the PATH variable. Since sqlplus is in $ORACLE_HOME/bin it should now be found.
I wouldn't recommend deviating from this standard. You should speak to your unix admin and Oracle dba to make sure this is setup correctly
I am trying to copy a file, export.txt from one directory to another within a .mshs script. I currently have:
shell copy 'E:\RPTG\Export.txt' 'E:\FCST\';
I'm getting an error that says "end of file breaks the statement."
Is there a command to copy a file with .mshs?
Thanks!
Typically you would perform the copy from a batch file itself. For example, your batch file would do the copy, run a MaxL script, and then do other things. That said, you can run shell commands from within MaxL if you need to (I don't usually recommend it though). In this case, you need to pass the whole statement to the shell command. Your statement should work if you write it like this instead:
shell "copy 'E:\RPTG\Export.txt' 'E:\FCST\'";
Note that I have enclosed your command in double quotes. There are some nuances to using double quotes and single quotes at the same time, but in this case you should be okay.
I would like your help with an issue.
I have a VB application located into a foler:
C:\folder\program.exe
I need to execute it using a *.bat file, but I also need to send a parameter like this:
CompRate&--&C:\folder\subfolder\CompRate&--&False&--&
When I execute the application using the IDE (VS2010) it goes to a Case statement (in this case 'CompRate') and generates a file with the same name into the folder 'C:\folder\subfolder\'
I have tried in the bat file this:
"C:\folder\program.exe" "CompRate&--&C:\folder\subfolder\CompRate&--&False&--&"
this
"C:\folder\program.exe" CompRate&--&C:\folder\subfolder\CompRate&--&False&--&
and other options.
Escape ampersands with ^
& seperates commands on a line.
&& executes this command only if previous command's errorlevel is 0.
|| (not used above) executes this command only if previous command's errorlevel is NOT 0
> output to a file
>> append output to a file
< input from a file
| output of one command into the input of another command
^ escapes any of the above, including itself, if needed to be passed to a program
" parameters with spaces must be enclosed in quotes
+ used with copy to concatinate files. E.G. copy file1+file2 newfile
, used with copy to indicate missing parameters. This updates the files modified date. E.G. copy /b file1,,
%variablename% a inbuilt or user set environmental variable
!variablename! a user set environmental variable expanded at execution time, turned with SelLocal EnableDelayedExpansion command
%<number> (%1) the nth command line parameter passed to a batch file. %0 is the batchfile's name.
%* (%*) the entire command line.
%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop. Single % sign at command prompt and double % sign in a batch file.
.
--
I save stored procedure code as files and then execute them in several different databases. I am trying to concatenate multiple files (100's). Every utility I use seems to create some special characters in the file that cause an error when i execute the script in sql.
Currently, i used
type *.sql > script.sql
in DOS. I am getting the following error in many places.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ''.
How can I find this character so I can do a find/replace? Thanks!
I do something very similar. Here's the text from batch file __QuickConcatenate_SQL.bat that will copy all *.sql files in that same folder into a new file:
REM Concatenate all .sql files into a single file
#ECHO OFF
CLS
COPY *.sql __ConcatenatedSQLScripts.sql /b
ECHO.
PAUSE
Note that "/b" parameter. I wrote this a long time ago, I recall including it to prevent the addition of oddball characters--CR, LF, EOF, something like that. (I never could figure out how to control the order that procedures were copied...)
Note also that this only works if the last line in every file is GO, followed by CR+LF (e.g. type "GO" and hit enter in SSMS).
Is it possible to use a Linux environment variable inside a .sql file? I'm using the copy/select query to write to an output file, and I'll like to put that directory in a variable. So I want to do something like:
COPY (SELECT * FROM a)
TO $outputdir/a.csv
Outputdir would be set in my environment. Is this possible?
You can store the result of a shell command inside a psql variable like this:
\set afile `echo "$outputdir/a.csv"`
COPY (SELECT * FROM a) TO :'afile';
Another (better in my opinion) solution is to use only psql variables, see this answer of mine about psql variables, which is similar to your example. A example for your case would be:
\set outputdir '/path/to/output'
\set afile :outputdir '/a.csv'
COPY (SELECT * FROM a) TO :'afile';
Note that, in the example, you need to set the variable inside the script file, but you can skip the first line if you set it when you call psql:
psql --set=outputdir="$outputdir" <conn parameters> -f /path/to/yourscript.sql
This appears to work for your use case, provided you single quote the output file name as I mentioned. It will escape any double quotes as well contained within the SQL.
psql -c "$(eval echo '"' $(<envvars.sql | sed 's/"/\\"/g') '"')"
Of course, note that if your file contains any dollar quoted variables, the shell is going to try to interpret as a variable, and your script will break, so you will need to escape any dollar signs you need preserved literally with a backslash.
See also the second snippet in the accepted answer to this question for a possibly more robust answer.
The accepted answer is correct for PostgreSQL running on Unix. Under Windows a different incantation is required for obtaining the value of the environment variable from the CMD shell and for avoiding the carriage return returned by the echo command.
\set afile `set /p=%outputdir%/a.csv`
COPY (SELECT * FROM a) TO :'afile';