tags:

views:

5152

answers:

3

I'm working on a Windows batch file that will bcp three text files into SQL Server. If something goes wrong in production, I want to be able to override the file names. So I'm thinking of doing something like this.

bcp.exe MyDB..MyTable1 in %1 -SMyServer -T -c -m0
bcp.exe MyDB..MyTable2 in %2 -SMyServer -T -c -m0
bcp.exe MyDB..MyTable3 in %3 -SMyServer -T -c -m0

I would like to be able to enter default names for all three files, to be used if the positional parameters are not supplied. The idea would be either to execute

myjob.bat

with no parameters, and have it use the defaults, or execute

myjob.bat "c:\myfile1" "c:\myfile2" "c:\myfile3"

and have it use those files. I haven't been able to figure out how to tell if %1, %2 and %3 exist and/or are null. I also don't know how to set those values conditionally. Is this possible? Any suggestions would be appreciated.

+2  A: 

To test for the existence of a command line paramater, use empty brackets:

IF [%1]==[] echo Value Missing

or

IF [%1] EQU [] echo Value Missing

The SS64 page on IF will help you here.

You can't set a positional parameter, so what you should do is do something like

SET MYVAR=%1

You can then re-set MYVAR based on its contents.

crb
+2  A: 
rem set defaults:
set filename1="c:\file1.txt"
set filename2="c:\file2.txt"
set filename3="c:\file3.txt"
rem set parameters:
IF NOT "a%1"=="a" (set filename1="%1")
IF NOT "a%2"=="a" (set filename2="%2")
IF NOT "a%3"=="a" (set filename1="%3")
echo %filename1%, %filename2%, %filename3%

Be careful with quotation characters though, you may or may not need them in your variables.

Stanislav Kniazev
+1; Almost any character or string will do: if not %1.==.; if not {%1}=={}; if not %1null==null...
Patrick Cuff
+1 for warning about quoting... the bane of batch programs!
RBerteig
+3  A: 

Both answers given are correct, but I do mine a little different. You might want to consider a couple things...

Start the batch with:

SetLocal

and end it with

EndLocal

This will keep all your 'SETs" to be only valid during the current session, and will not leave vars left around named like "FileName1" or any other variables you set during the run, that could interfere with the next run of the batch file. So, you can do something like:

IF "%1"=="" SET FileName1=c:\file1.txt

The other trick is if you only provide 1, or 2 parameters, use the SHIFT command to move them, so the one you are looking for is ALWAYS at %1...

For example, process the first parameter, shift them, and then do it again. This way, you are not hard-coding %1, %2, %3, etc...

The Windows batch processor is much more powerful than people give it credit for.. I've done some crazy stuff with it, including calculating yesterday's date, even across month and year boundaries including Leap Year, and localization, etc.

If you really want to get creative, you can call functions in the batch processor... But that's really for a different discussion... :)

Oh, and don't name your batch files .bat either.. They are .cmd's now.. heh..

Hope this helps.

LarryF
Thanks for the suggestions. Just curious... Why .cmd instead of .bat?
John M Gant
Actually, I think this is a throw-back. BAT is for DOS, and CMD is for WinNT.. But, the real reason is, at one time, you had cmd.exe, and command.com. .cmd was related to cmd.exe, it was the parser for those. I think it also makes you look cooler, but I can't confirm that. :)
LarryF
There is a subtle difference between them, and Raymond Chen had an Old New Thing post about it that I can't find right now... Google is not being my friend. See also this SO Q: http://stackoverflow.com/questions/148968/windows-batch-files-bat-vs-cmd
RBerteig