Retry a sql query in case of failure in batch - sql

This script processes all the sql files in a given folder and outputs the result to a csv. Do you have any ideas how could I adapt it to retry the sql file in case of error or failure?
#ECHO OFF
SET SQLCMD="C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE"
SET PATH="C:\Users\username\Desktop\Scripts\Reports\sql"
SET SERVER="localhost"
SET DB="database"
SET LOGIN="username"
SET PASSWORD="password"
SET OUTPUT="C:\Users\username\Desktop\Scripts\Reports\output_%date%-%time:~0,2%-%time:~3,2%-%time:~6,2%.csv"
CD %PATH%
ECHO %date% %time% > %OUTPUT%
for %%f in (*.sql) do (
%SQLCMD% -S %SERVER% -d %DB% -E -i %%~f >> %OUTPUT% -W -w 1024 -s";")
Thank you!

You cant test the ERRORLEVEL environment variable. typically a zero ERRORLEVEL value means success. also you need to enable delayed expansion to check it inside a block.
something like this may help,
SetLocal EnableDelayedExpansion
for %%f in (*.sql) do (
Set /a success=1
for /L %%w in (1,1,5) do ( rem retry five times
if !success! NEQ 0 (
%SQLCMD% -S %SERVER% -d %DB% -E -i %%~f >> %OUTPUT% -W -w 1024 -s";"
if !ERRORLEVEL! EQU 0 set /a success=0
)
)
if !success! NEQ 0 (
rem sql failed, log or advise
)
)
EndLocal
another important point, be careful with the PATH environment variable. you should better use another name as SQL_PATH or MY_PATH.
or you can use PUSHD & POPD to change your working dir
#echo off
SET ...
rem save current dir and jump to...
pushd "C:\Users\username\Desktop\Scripts\Reports\sql"
for %%f in (*.sql) do (
...
...
)
rem restore dir saved by pushd
popd

Related

batch file use parameter and string to create path

I know there's a ton of stuff out there on this but I just can't make it work. What I want to do is
#ECHO OFF
FOR /D %%D IN (*) Do (
ECHO %%D
if not exists %%D.mp4 (
rem cd %%D
rem "C:\Program Files\Handbrake\HandBrakeCLI.exe" -i "VIDEO_TS" -o "..\%%D.mp4" --preset="High Profile" --x264-preset slow
echo not exists
)
rem cd ..\
)
I left the extra stuff in there so you could see that I actually need the /D rather than a /R. basically I'm converting the VIDEO_TS folder that is in an other folder into an mp4 of the parents name and putting it in the root.
the problem is checking if the file already exists. I can't figure out how to create a path that "exists" will recognize out of the var %%D and the suffix .mp4
Any help would be greatly appreciated.
Thanks,
R
There are two errors here
The keyword is EXIST, not EXISTS.
You need to enclose the variable in double-quotes, due to spaces in filenames.
Example:
#ECHO OFF
FOR /D %%D IN (*) DO (
ECHO %%D
IF NOT EXIST "%%D.mp4" (
ECHO not exists
)
)
Further, if you uncomment those other lines, you'll have issues because the cd .. is not at the same branching level as the cd "%%D" (note I added double-quotes here). You should move that into the IF block.
However, instead of changing directory, you could simply pass "%%D\VIDEO_TS" to Handbrake.
FOR /D %%D IN (*) DO (
IF NOT EXIST "%%D.mp4" (
echo Encoding %%D ...
"C:\Program Files\Handbrake\HandBrakeCLI.exe" -i "%%D\VIDEO_TS" -o "%%D.mp4" --preset="High Profile" --x264-preset slow
)
)
Or you could use pushd and popd:
FOR /D %%D IN (*) DO (
pushd .
IF NOT EXIST "%%D.mp4" (
cd "%%D"
echo Encoding %%D ...
"C:\Program Files\Handbrake\HandBrakeCLI.exe" -i "VIDEO_TS" -o "..\%%D.mp4" --preset="High Profile" --x264-preset slow
)
popd
)

Populate a batch from a file

I have been trying to work this 1 out it's a fairly simple batch but I'm pretty much lost, the searches got my close but none seemed to work so I'm hoping somebody can help with this.
I have a batch file, it is far from optimized but basically what I am trying to do now is use the ping I have running in the batch which is written to check.csv should then populate the individual IP's at the beginning (hope that makes sense).
in a nut shell
The variables at the beginning should be populated from check.csv
Here is the code
'#echo off
rem set the individual IP addresses
Rem these are manually set at present, I want these set automatically from check.csv which is created at the end of this file at present but will be moved infront..
set sarah=10.1.14.106
set richard=10.1.15.135
set kathh=10.1.12.79
edited out a number of these to reduce the code on screen for you, but they are all the same format, name & IP
rem set the individual profile name
set n1=sharman
set n2=rburrell
removed more of the same (just duplicates the above code for a different user)
rem set the computer name
set sarahPC=PB7B237
set richardPC=PB1VAL9
removed more of the same
REM set the main install paths
set M3="C:\Users\dclare\Documents\VW Compiler\Installers\M3.exe"
set H3="C:\Users\dclare\Documents\VW Compiler\Installers\H3.exe"
set MooresInst="C:\Users\dclare\Documents\VW Compiler\Catalogues\PD PS\Catalogue"
Rem menu
#echo off
cls
:start
echo.
echo 1 Ping
echo 2 List
echo 3 DBase Installers
echo 4 EXE Installers
echo 5 End
echo.
#CHOICE /C:12345
if errorlevel 5 goto End
if errorlevel 4 goto EXEInstallers
if errorlevel 3 goto DBase
if errorlevel 2 goto List
if errorlevel 1 goto Ping
goto End
:End
Pause
Exit
:EXEInstallers
echo EXE Installers
echo.
echo Upload folder
Xcopy %M3% "S:\# All Public\Information Technology\CAD\VWorlds" /s /y /q
Xcopy %H3% "S:\# All Public\Information Technology\CAD\VWorlds" /s /y /q
echo.
echo %sarah%
Xcopy %M3% "\\%sarah%\c$\Users\%n1%\Desktop\" /s /y /q
Xcopy %H3% "\\%sarah%\c$\Users\%n1%\Desktop\" /s /y /q
echo.
echo %richard%
Xcopy %M3% "\\%richard%\c$\Users\%n2%\Desktop\" /s /y /q
Xcopy %H3% "\\%richard%\c$\Users\%n2%\Desktop\" /s /y /q
echo.
removed more of the same (just duplicates the above code for a different user)
goto Start
:DBase
echo Database Installers
echo.
echo %sarah%
Xcopy %MooresInst% "\\%sarah%\c$\Virtual Worlds\Catalogue" /s /y /q
echo.
echo %richard%
Xcopy %MooresInst% "\\%richard%\c$\Virtual Worlds\Catalogue" /s /y /q
echo.
removed more of the same (just duplicates the above code for a different user)
echo
Goto Start
:List
echo.
echo This is a list of the IP's used currently, check against any that fail.
echo.
echo Name Puter IP
echo sarah %sarahPC%%sarah%
echo richard %richardPC% %richard%
echo kathh %kathhPC% %kathh%
echo amarie %amariePC% %amarie%
removed more of the same (just duplicates the above code for a different user)
echo.
Pause
Goto Start
:Ping
#echo off
if exist "C:\Users\dclare\Documents\VW Compiler\Copy to Desktop\Results.csv" Del /s /q "C:\Users\dclare\Documents\VW Compiler\Copy to Desktop\Results.csv"
Echo Pinging list...
set ComputerList=list.txt
pause
Echo Computername,IP Address>Final.csv
setlocal enabledelayedexpansion
for /f "usebackq tokens=*" %%A in ("%ComputerList%") do (
for /f "tokens=3" %%B in ('ping -n 1 -l 1 %%A ^|findstr Reply ^|^| echo Not found Failed:') do (
set IPadd=%%B
echo %%A,!IPadd:~0, -1!>>Check.csv
))
pause
Goto Start'
here is the check.csv file contents
PB1VAL9 10.1.15.135
PB7B218 Failed
PB1VAL8 10.1.15.111
PB7B210 10.1.5.253
removed more of the same (just duplicates the above code for a different user)
Try this routine out to set your variables to ip addresses:
echo off
for /f "usebackq tokens=1,2" %%a in ("check.csv") (
echo setting %%a=%%b
set "%%a=%%b"
)
With this ping routine it shows if it is online or offline. I had to guess what you were trying to do as we don't have your files to test it.
Give us a sample of Check.csv if you want to populate a set of variables with the IP addresses inside it.
:Ping
#echo off
Del /s /q "C:\Users\dclare\Documents\VW Compiler\Copy to Desktop\Results.csv" 2>nul
Echo Pinging list...
set "ComputerList=list.txt"
pause
Echo Computername,IP Address>Final.csv
for /f "usebackq delims=" %%A in ("%ComputerList%") do (
ping -n 1 -l 1 %%A >nul
if not errorlevel 1 (
>>Check.csv echo %%A,online
) else (
>>Check.csv echo %%A,offline
)
)
pause
Goto Start

How to execute SQL scripts in alphabetical order using a batch file

Is it possible to execute all SQL scripts in a folder in alphabetical order using a batch file ?
Currently I uses the following code but it executes the scripts in the order in which they are kept instead of executing it in alphabetical order
SET Database=<<DatabaseName>>
SET ScriptsPath=<<FolderPath>>
SET ServerName=<<ServerName>>
IF EXIST "%ScriptsPath%output_CCF.txt" del "%ScriptsPath%output_CCF.txt"
type NUL > "%ScriptsPath%output_CCF.txt"
FOR /R "%ScriptsPath%" %%G IN (*.sql *.up) DO (
sqlcmd -d %Database% -S %ServerName% -i "%%G" -o "%%G.txt"
echo .................................................
>> "%ScriptsPath%output_CCF.txt"
echo Executing: "%%G" >> "%ScriptsPath%output_CCF.txt"
echo ...................................>> "%ScriptsPath%output_CCF.txt"
copy "%ScriptsPath%output_CCF.txt"+"%%G.txt" "%ScriptsPath%output_CCF.txt"
del "%%G.txt"
)
If you use the /F option of the FOR command, then you can use another command to generate the set of data to be iterated over.
Use this FOR statement and I believe you'll find the result you're looking for.
FOR /F "usebackq" %%G IN (`dir /ON /B *.sql *.up`) DO ...
This uses the dir command to generate the set of files to use. The /ON argument orders the files by name and the /B argument provides a bare format (no heading information or summary) of the file names.
For more details on the arguments check the help for either of the commands from the command line dir /? and for /?

Howto add a string to the 'type <filename>' DOS command before merging into file?

Question: I've several text files containing sql create table/column/view/storedProcedure textfiles. Now I want to merge the textfiles into one textfile.
I go into the directory, and type:
type *.sql >> allcommands.sql
Now to problem is I should add the text ' GO ' after every file's content.
I can append Go by doing
type *.sql >> allcommands.sql & echo GO >> allcommands.sql
But this only inserts go once.
How can I accomplish this with DOS commands ?
You want something like this:
for %%f in (*.sql) do type %%f >>allcommands.sql & echo GO >> allcommands.sql
The %% is for use in a batch file. If you're not running it from a batch file you only need single % signs.
Try this one
for %%f in (*.sql) do (
type %%f >>allcommands.sql
echo. >> allcommands.sql
echo GO >> allcommands.sql
echo. >> allcommands.sql )
it adds newline then go for each SQL file. it works for me try it.
Use copy to concatenate the first file with a file with "GO" text, then concatenate again with the second file.
#echo off
CLS
::concat.bat outfile.sql
setlocal EnableDelayedExpansion
If EXIST GOTMP.TMP DEL /Q GOTMP.TMP
Echo GO>GOTMP.TMP
ECHO.>>GOTMP.TMP
If EXIST "%~1" DEL /Q "%~1"
Echo.>"%~1"
for /f "tokens=*" %%A in ('dir /a-d /on /b "*.sql"') do call :perfaction "%%A%" "%~1"
ECHO Done Generating Output "%~1"
ECHO.
pause
Goto :EOF
:perfaction
ECHO "%~1"
copy "%~2"+"%~1"+GOTMP.TMP "%~2"
GOTO :EOF

sql deploy with dos

How can I customize the the FOR command below to loop through the files inside the Database folder following the order of the number prefixed in the file name?
FOR /R ../Database %%f IN (*.sql) DO sqlcmd -S %1 -d %2 -U %4 -P %5 -i "%%~f" >> Logs/%2_DBInstall.log || goto errors
Database folder contains:
001_usp_procedure1.sql
002_ups_procedure2.sql
Thanks very much,
Please try the following
del temp.txt
del temp1.txt
for /F "usebackq " %%F IN (`dir /b /s /o:n "../Database/*.sql"`) DO (
echo %%~nF / %%F >> temp.txt
)
sort temp.text temp1.text
for /F "tokens=1,2 delims=/" %%i IN (temp1.txt) DO sqlcmd -S %1 -d %2 -U %4 -P %5 -i "%%j" >> Logs/%2_DBInstall.log || goto errors
It should work for recursive directories too (process is sorted by global filename without taking account of the path ... did I understand the problem?)
Please note that two temp files are being used. Be careful with the names (or use real temp files)