Call SQL SP from dos batch file - sql-server-2005

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.

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

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

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.

Creating a bat file which executes SQL scripts

I have a folder into which a number of MSQL scripts get dropped into after each weekly sprint. For example, 10 scripts were placed into the folder today. I had to then open each script individually and run it against the applicable database. The database that it needs to be run against is in the name of the file.
e.g. [2] [CRMdata]UpdateProc.sql
The [2] represents the sequence in which it is run, so script [1] needs to be run before it.
[CRMdata] is the database I have to run it against.
This process is very tiresome, especially if there are 50 scripts to run sequentially.
I was wondering if there was an easier way to do this?
Perhpas a .bat file, which reads the filename, and executes the scripts sequentially based on the script number, as well as executing it against the database specified in the file name.
Any help is much appreciated.
Thanks.
First, when you need to run things, consider using SQL Server Job Agent. This is a good way to schedule simple things.
For a task like this, I would recommend PowerShell in combination with "sqlcmd". This command is actually the answer to your question, since it will run scripts from the command line.
However, go a step further. Schedule a job that runs once per week (or whenever you want it run). Have it consist of one step, a PowerShell script. This can then loop through all the scripts in the directory, extract the file name from the name, and run the script using sqlcmd. Along the way, also log what you are doing in a table so you can spot errors.
I don't know anything about executing SQL with MSQL. You will have to work out how to run each script against the proper database using whatever command-line utility is provided for MSQL.
I can help you with a batch file that will sort the SQL files in the correct sequence order, and parse out the name of the database.
The job is much easier in batch if the sequence numbers are zero prefixed to be a constant width. I'm assuming it is OK to rename the files, so that is what this solution does.
I also assumed you will never have more than 999 files to process. The code can easily be modified to handle more.
Some changes will have to be made if any file names contain the ! character because delayed expansion will corrupt the expansion of the FOR variables. But that is an unlikely problem.
#echo off
setlocal enableDelayedExpansion
:: Change the definition to point to the folder that contains the scripts
set "folder=sqlCodeFolder"
:: The mask will only match the pattern that you indicated in your question
set "mask=[*] [*]*.sql"
:: Rename the .sql files so that the sequence numbers are zero prefixed
:: to width of 3. This enables the default alpha sort of the directory to be
:: in the proper sequence
for /f "tokens=1* delims=[]" %%A in ('dir /b "%folder%\%mask%"') do (
set seq=00%%A
ren "%folder%\[%%A]%%B" "[!seq:~-3!]%%B"
)
::Process the renamed files in order
for %%F in ("%folder%\%mask%") do (
for /f "tokens=2 delims=[] " %%D in ("%%~nF") do (
rem %%F contains the full path to the sql file
rem %%D contains the name of the database, without enclosing []
rem Replace the echo line below with the proper command to run your script
echo run %%F against database [%%D]
)
)

How to add a variable amount of arguments to exec in tcl?

I've been working with TCL for some time now, and I have spent a long time trying to do the following (it seems easy and I think it should be, but I can't get it right):
I need to execute an external program by means of a tcl script. For that, I use the exec command. For using this external program, I need to input a variable amount of files. If I called this program straight from a cmd window, it would be something like:
C:\>myprogram -i file1 -i file2 -i file3 (etc., etc.)
However, when trying to implement this in a dynamic/variable way through tcl I get into trouble. The way I do it is by storing in some variable myvar all the "-i filex" I need (done in a loop), and then pass that as a parameter to the exec command. It would look something like:
exec myprogram $myvar
Doing that apparently creates some issues, because this myprogram fails to "see" myvar. I'm guessing that there is some sort of hidden terminator or some clash of different types of arguments that makes that in the end the exec command "sees" only myprogram.
So, my question is, does anyone know how to insert variable arguments into a call to exec?
You can use {*} or eval. See this question for example.
Specializing for your case:
Tcl 8.5 (and later):
exec myprogram {*}$myvar
Tcl 8.4 (and before):
eval [list exec myprogram] [lrange $myvar 0 end]
# Or...
eval [linsert $myvar 0 exec myprogram]
That's right, the old version is ugly (or non-obvious, or both). Because of that, people tended to write this instead:
eval exec myprogram $myvar
but that was slower than expected (OK, not so relevant when running an external program!) and has hazards when $myvar isn't a canonically-formatted list due to the way that eval works. It used to catch out even experienced Tcl programmers, and that's why we introduced new syntax in 8.5, which is specified to be surprise-free and is pretty short too.