Is there batch script command where I can change variable values in a .sql file? - sql

I am creating a batch file where I am restoring a database from an IP address and then executing a couple .sql files onto the database. In a couple of the .sql files there are variables declared and set. But this process has to be done on many machines with different values for each variable in each machine.
So I'm able to restore the database through user input of the IP, but I'm not sure how to use the batch script command to change the variable values.
For example, in one of the .sql files, a variable #store was declared and set to some random number. I want to change that number through the batch file.
I am using windows and sql server express 2008 r2

You can use "scripting variables" with SQLCMD.
Here's an example from that MSDN page:
You can also use the -v option to set a scripting variable that exists in a script. In the following script (the file name is testscript.sql), ColumnName is a scripting variable.
USE AdventureWorks2012;
SELECT x.$(ColumnName)
FROM Person.Person x
WHERE c.BusinessEntityID < 5;
You can then specify the name of the column that you want returned by using the -v option:
sqlcmd -v ColumnName ="FirstName" -i c:\testscript.sql
To return a different column by using the same script, change the value of the ColumnName scripting variable.
sqlcmd -v ColumnName ="LastName" -i c:\testscript.sql

If you are working on a Unix / Linux system, you can use sed to search a string.
Example: Assuming you need to replace 127.0.0.1 to 192.168.1.1, you can use the following instruction:
$ sed 's/127.0.0.1/192.168.1.1/g' script.sql > newScript.sql
This will replace the old ip in script.sql and will save a copy of this script in newScript.sql.
On windows, I don't know how to do it, but you can always download and install Cygwin to do exactly as above.
Hope this helps you.

Related

Run sql plus commands on Unix machine

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

How sql loader scrip is working?

Currently I'm working with Exasol database first time and came across one script which is responsible to run sql script written in .sql file.
Here is the script
C:\Program Files\EXASOL\EXASolution\EXAplus\exaplusx64.exe -configDir EXASolutionConfig -profile profile_PROD_talend -q -f D:/Data/Customer/PROD/EXASolution_SQL/EXASOL_data_script.sql -- databaseName tableName /exasolution/StageArea/fileName.csv
I want to know, how this script is working and what its doing actually ? What I understood so far is below
First "C:\Program Files\EXASOL\EXASolution\EXAplus\exaplusx64.exe " is starting a Exasol on command line and then its pointing to the script where .sql file is located.
Not getting:
1) What this part is doing "-configDir EXASolutionConfig -profile profile_PROD_talend -q -f "?
2) What are these identifiers doing "-q -f "?
3)After launching exaplusx64.exe, Is exasol going to connect with database and table name mentioned in script ? If then How cav file is paying its role in this script ? I mean in .sql there is just an sql statement, If its taking data from file then how ? I'm not getting this ..!!
Please share your comments
1) This where you say to Exasol to read the profile profile_PROD_talend in the folder EXASolutionConfig and execute the file D:/Data/Customer/PROD/EXASolution_SQL/EXASOL_data_script.sql in quiet mode (-q).
From the manual:
-configDir *This is not actually in the EXASOL manual, I assume it's the folder with the profiles, or maybe it does nothing*
-profile Name of connection profile defined in <configDir>/profiles.xml (profiles can be edited in the GUI version). You can use a profile instead of specifying all connection parameters.
-q Quiet mode which suppresses additional output from EXAplus.
-f Name of a text file containing a set of instructions that run and then stop EXAplus.
2) Quiet mode and flag for the name of the file.
3) When you run this command EXAPlus connects to the db using the information provided in the profile and it will execute the .sql file passed.
Now things become interesting, the -- allows you to pass some arguments to the .sql file. So you are passing three parameters (databaseName, tableName, and /exasolution/StageArea/fileName.csv). If you open the sql script you will find &1, &2, and &3, these are the placeholders for the parameters passed by your command.
From the manual again:
-- <args> SQL files can use arguments given over via the parameter “-- ” by evaluating the variables &1, &2 etc. .
For example, the file test.sql including the content
--test.sql
SELECT * FROM &1;
can be called in the following way:
exaplus -f test.sql -- dual

Multiple sql files in a directory which is in turn used in an unix script

I have a script say sql_result.sh in directory /tmp/SQL_QUERY which just calls a sql script in the same location and executes the sql commands.
Code:
sqlplus -S $MY_UN/$MY_PW#$MY_DB <<!
set serveroutput on;
#/tmp/SQL_QUERY/sql_file1
quit
!
However, if I have say 2 SQL files sql_file1.sql and sql_file1.sql_new in that directory. Which of the either sql scripts will my unix script pick? How and why?
Thanks
Short answer: normally sql_file1.sql
The default extension is .SQL as explained in the docs for #:
file_name[.ext]
Represents the script you wish to run. If you omit ext, SQL*Plus assumes the default
command-file extension (normally SQL). For information on changing the default extension,
see the SUFFIX variable of the SET command.
As it says, you can use the SET command to change which extension is used, or you can specify the extension in the script explicitly.
The SET command says:
Sets the default file extension that SQL*Plus uses in commands that refer to scripts. SUFFIX does not control extensions for spool files.
Example
To change the default command-file extension from the default, .SQL to .UFI, enter
SET SUFFIX UFI
If you then enter
#EXAMPLE
SQL*Plus will look for a file named EXAMPLE.UFI instead of EXAMPLE.SQL.
(Note that a SET command might be present in your LOGIN file.)

Using an environment variable in a PSQL script

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';

Call SQL SP from dos batch file

I have a MS SQL 2005 stored proc which takes an out parameter. How can I call this from a dos batch file and get the value of the out param? I know I have to use sqlcmd, but cant find anyting in there by which I can pass an out param and access its value in dos batch file.
Thanks
vikram
I do this kind of thing all the time (like so) with standard T-SQL, but you might be able to do something like this with a stored procedure if you edit the stored procedure to show a one line result set.
sqlcmd -b -S %COMPUTERNAME% -E -d %DBNAME% -Q "exec getXMLLocation;" -h-1
-o SearchResult.txt
set /p URI=<SearchResult.txt
#echo The XML file URI is: %URI%
In DOS, you will get any information returned in the standard out, but you cannot easily manipulate this. Must this be DOS? Is PowerShell an option, as you have more capabilities with PowerShell (heck even WSH is a better option for DOS if you need to store this value and not just show it in the command prompt).
Adding this based on comment this must be DOS. Here are my thoughts:
First, I would use the out macro statement to direct to stdout:
: out stdout
Once you have output in stdout, you can use DOS commands to direct it to variables you have set up in DOS. stdout is handle 1 in DOS.
The one issue I can think that might make this fail is if other items are cluttering up stdout. I would not want to parse through a lot of junk.