Pass a parameter from one batch file to another batch file - sql

I have two batch files.
First extracts date from and creates folder in \YEAR\MONTH\DATE format.
#echo off
setlocal enabledelayedexpansion
:: Extract date fields
for /f "tokens=1-4 delims=/-. " %%i in ('date /t') do (
set v1=%%i& set v2=%%j& set v3=%%k
if "%%i:~0,1%%" gtr "9" (set v1=%%j& set v2=%%k& set v3=%%l)
for /f "skip=1 tokens=2-4 delims=(-)" %%m in ('echo.^|date') do (
set %%m=!v1!& set %%n=!v2!& set %%o=!v3! ))</br>
:: Final set for language independency
set year=%yy%%aa%
set month=%mm%
set day=%dd%
:: Make Dir
set root=f:\
::Create folder of today's date
if exist %root% goto L2
goto L3
:L2
if not exist %root%\%year% md %root%\%year%
:L3
if exist %root%\%year%\%month% goto L5
:L4
if not exist %root%\%year%\%month% md %root%\%year%\%month%
:L5
md %root%\%year%\%month%\%day%
:: Detete folder older than '3' days
forfiles /p "%root%%year%\%month%" /s /d -3 /c "cmd /c IF #isdir == TRUE rd /S /Q #path"
echo.
pause
creates a backup of database
echo off
cls
echo -- BACKUP DATABASE --
::set db name
set DATABASENAME='db_name'
:: set path and format
set BACKUPFILENAME='path\%DATABASENAME%.bak'
:: set server name
set SERVERNAME='server name'
echo.
::backup execution
sqlcmd -S %SERVERNAME% -Q "BACKUP DATABASE [%DATABASENAME%] TO DISK = N'%BACKUPFILENAME%' WITH INIT , NOUNLOAD , NAME = N'%DATABASENAME% backup', NOSKIP , STATS = 10, NOFORMAT"
echo.
Now I want to call the second batch file from first and also pass the parameters like root, year, month, date from first to second.
I've tried both codes individually and its working perfectly. How can I pass the parameters. Please help

If you call second batch from first one, something like
call backupDP.cmd
both files share the same environment, so, both see the same variables. No need to pass anything, the second batch already has all the data.

Related

Grouping files and 'splitting' by number and copying them inside folders

I have 5000+ files inside a directory.
I want to manage these files 'splitting' every 500 files so first pack is copied inside folder1, pack2 of other 500 files is copied in folder2 and so on.
Which .bat script can I use ?
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
SET /a destcount=0
SET /a maxcount=5
SET /a filecount=maxcount
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
SET /a filecount +=1
IF !filecount! geq %maxcount% (
SET /a filecount=0
SET /a destcount +=1
MD "%destdir%\folder!destcount!"
)
ECHO(COPY "%sourcedir%\%%a" "%destdir%\folder!destcount!\"
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
maxcount sets the number of files to assign to a group.
The required COPY commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(COPY to COPY to actually copy the files. Append >nul to suppress report messages (eg. 1 file copied)
Essentially, count the number of transfers and increment the destination-directoryname each time a group is complete, using delayedexpansion to access the run-time values of the counters

NetApp SnapManager for SQL Server Update backup script

I was very disappointed that NetApp just doesn't add Feature to automatically update the (MS)SQL Job automatically every time a new Database gets created. (for a Full backup)
So i now want to share with you what I did to automatically add a new Database to out full SQL backup job.
Maybe someone has some ideas on how to make things a little bit more efficient or create not so much temporary files :)
Just Create a SQL job with executes the flowing batch file to update the NetApp SnapManager SQL Job.
#echo off
set SQLinstance=YOUR_SQL_SERVERNAME
REM if something differs
set SQL_SERVER=%SQLinstance%
REM SQL Verify Instalce
set SQL_VERIFY=ANOTHER_SERVERNAME\VERIFY
set db_list=list_%SQL_SERVER%.txt
set db_list_wo_summary=list_new_%SQL_SERVER%.txt
set linecount_file=linecount_%SQL_SERVER%.txt
set output-Full-User-file=output-Full-%SQL_SERVER%.txt
set output-Inc-User-file=output-Inc-%SQL_SERVER%.txt
set SQLCMD="C:\Program Files\Microsoft SQL Server\110\Tools\Binn\sqlcmd.exe"
set arg_start=C:\Program Files\NetApp\SnapManager for SQL Server\SmsqlJobLauncher.exe new-backup -svr ''%SQLinstance%'' -d ''%SQLinstance%'',
set arg_end_full= -ver -verInst ''%SQL_VERIFY%'' -mp -mpdir ''C:\Program Files\NetApp\SnapManager for SQL Server\SnapMgrMountPoint'' -RetainBackupDays 8 -RetainShareBackupDays 17 -cpylgbkshare COPYLOG_TOSHARE -lb -bksif -RetainSnapofSnapInfoDays 17 -rudays 1 -gen -mgmt daily
set arg_end_incremental= -ver -verInst ''%SQL_VERIFY%'' -mp -mpdir ''C:\Program Files\NetApp\SnapManager for SQL Server\SnapMgrMountPoint'' -RetainBackupDays 8 -RetainShareBackupDays 17 -cpylgbkshare COPYLOG_TOSHARE -lgbkonly -bksif -RetainSnapofSnapInfoDays 17 -gen -mgmt daily
set SQL_QUERIE="SELECT NAME FROM master.sys.databases AS dtb WHERE NOT (CAST(case when dtb.name in ('master','model','msdb','tempdb') then 1 else dtb.is_distributor end AS bit)=1) ORDER BY NAME"
set JOBNAME_FULL_BACKUP=jobname_full
set JOBNAME_INCREMENTAL_BACKUP=jobname_incremental
set SQL_UPDATE_COMMAND_START="UPDATE msdb.dbo.sysjobsteps SET command='"
set SQL_UPDATE_COMMAND_END=' FROM msdb.dbo.sysjobs, msdb.dbo.sysjobsteps WHERE msdb.dbo.sysjobs.job_id = msdb.dbo.sysjobsteps.job_id AND name = '%JOBNAME_FULL_BACKUP%'"
set SQL_UPDATE_COMMAND_END_INC=' FROM msdb.dbo.sysjobs, msdb.dbo.sysjobsteps WHERE msdb.dbo.sysjobs.job_id = msdb.dbo.sysjobsteps.job_id AND name = '%JOBNAME_INCREMENTAL_BACKUP%'"
REM Delete Old files (just to be sure)
del %db_list_wo_summary% %db_list% %linecount_file%
REM Get a List af all Databases and write them into a File
%SQLCMD% -E -S %SQLinstance% -o %db_list% -h -1 -s "," -W -Q %SQL_QUERIE%
setLocal EnableDelayedExpansion
REM Remove the last 2 Lines (one is a summary line, ant the other is empty)
set count=
for /f %%x in ('type %db_list% ^| find /c /v ""') do set /a lines=%%x-2
copy /y nul %tmp%\tmp.zzz > nul
for /f "tokens=*" %%x in ('type %db_list% ^| find /v ""') do (
set /a count=count+1
if !count! leq %lines% echo %%x>>%tmp%\tmp.zzz
)
move /y %tmp%\tmp.zzz %db_list_wo_summary% > nul
REM removes all linebreaks and adds a ' on every star and ending of the string (and adds a comma)
for /f "tokens=* delims= " %%a in (%db_list_wo_summary%) do (set s=!s!%%a'', '')
REM removes the last four chars (, '')(comma, space, and 2 '')
set s=!s:~0,-4!
REM counts the lines of the file NOT containing the string XXXYYYZZZ (basicaly a line count)
type %db_list_wo_summary% | find /V /C "XXXYYYZZZ" > %linecount_file%
for /f "tokens=* delims= " %%c in (%linecount_file%) do (set cn=%%c)
REM Creates the final string for the SQL job
set s1=%arg_start% ''%CN%'', ''!s!%arg_end_full%
set s2=%arg_start% ''%CN%'', ''!s!%arg_end_incremental%
REM Update the SQL Job step command with the new string via SQLCMD
%SQLCMD% -E -S %SQLinstance% -Q %SQL_UPDATE_COMMAND_START%%s1%%SQL_UPDATE_COMMAND_END%
%SQLCMD% -E -S %SQLinstance% -Q %SQL_UPDATE_COMMAND_START%%s2%%SQL_UPDATE_COMMAND_END_INC%
REM deleting the temp file
del %db_list_wo_summary% %db_list% %linecount_file%
I hope this can help anyone make things a bit more efficient.
The answer is above :)
Hopefully someone will find that user full, or at least inspiring ;)
Don't specify a database to backup at all ... then SMSQL will backup all databases, also the new ones

save the result of a operation into a variable within a .BAT file

I have the following BAT file working ok:
it connects to an specific sql server and select getdate()
what I really wanted is to test whether the server is connectable.
I would like something like:
set is_connectable = call sqlcmd.exe %%SERVITORE%%
is there any way I could achieve this?
thanks and regards
marcelo
#echo off
color fc
cls
echo.
#ECHO --- BEGIN THE SCRIPT 1 ----
echo.
#echo the SERVITORE is "%1"
echo.
echo.
if "%1"=="" GOTO USAGE
set SERVITORE=-Stcp:%1% -Q " USE MASTER select getdate() "
call sqlcmd.exe %%SERVITORE%%
color 6
GOTO THE_END
:USAGE
echo.
echo USAGE:
echo.
ECHO the first parameter is the SERVITORE server.
echo example 1 SERVITORE108
echo.
ECHO the second parameter is optional
echo but if not supplied the default is \\SERVITORE\folder2$
echo.
echo ATB
echo.
:THE_END
color 8
It is easy to run a query and set the result to a DOS environment variable. For instance, you can do the following to get the date/time from the SQL Server instance (SQL Server is running locally in my instance):
for /f "skip=2 delims=" %%i in ('sqlcmd -S localhost -E -Q "set nocount on; select getdate() as [Now]"') do set is_connectable=%%i
However, the is_connectable environment variable set in this example will have an arbitrary value, which will make it hard to evaluate. Since you are just trying to verify that the SQL Server is there, alive, and responsive, you should run a query that creates a more predictable output, like this:
#echo off
:: Make sure the variable is undefined to start with
set is_connectable=
:: Make the connection and run a query that should always return '1'
for /f "skip=2 delims= " %%i in ('sqlcmd -S localhost -E -Q "set nocount on; select 1 as [Rows] into #temp; select ##rowcount as [Rows]; drop table #temp"') do set is_connectable=%%i
:: Verify if SQL Server is avaialble
if not defined is_connectable goto NotFound
if "%is_connectable%"=="1" goto Found
goto UnknownError
:Found
echo SQL Server was found and returned '1' as expected...
goto TheEnd
:NotFound
echo SQL Server was not found...
goto TheEnd
:UnknownError
echo SQLServer was found, but the return value was '%is_connectable%' instead of '1'...
goto TheEnd
:TheEnd

Batch file read from largest registry sub-key?

I am trying to modify my batch script to get the install path for a piece of software, however it needs to be version independent and the install path is stored in a version sub-key, so basically what I am looking to do is detect the greatest version sub-key and get the install path from there.
Here is what the code for getting the registry value looks like now:
FOR /F "skip=2 tokens=2,*" %%A IN ('REG.exe query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node......\6.30" /v "InstallLocation"') DO set "InstallPath=%%B"
Basically I want to not be dependent on the "6.30" part on the end of the key address, how can I do this?
Since I do not know which exact software you are looking at, I will reference Adobe Reader on Winodws 7 x64.
Answer:
The following example will output all of the sub keys within the parent.
for /f "delims=" %%A in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Adobe\Acrobat Reader"') do if not "%%~A"=="" echo.%%~nxA
Output:
9.5
10.0
11.0
Sample:
From there it would just be a matter of remembering the largest and using it in the next query for the value data.
#echo off
setlocal EnableDelayedExpansion
set "xVersion="
set "xPath="
:: Retrieve Greatest Version
for /f "delims=" %%A in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Adobe\Acrobat Reader"') do (
if not "%%~A"=="" if "%%~nxA" GTR "!xVersion!" set "xVersion=%%~nxA"
)
:: Validate Version
if "%xVersion%"=="" goto :eof
:: Retrieve Install Path
for /f "tokens=1,2,*" %%A in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Adobe\Acrobat Reader\%xVersion%\Installer" /v Path') do (
set "xPath=%%~C"
)
:: Show Results
echo.%xPath%
endlocal
Output:
C:\Program Files (x86)\Adobe\Reader 10.0\
Bonus:
If you want to validate that the %%~nxA is a number, here is a batch routine of mine.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:IsNumber <xReturn> <xInput> [xDelims]
:: Return true if the input is a base 10 number, else return false.
:::: Does not allow any seperators unless specified by xDelims. ,.[tab][space]
setlocal
if not "%~2"=="" set "xResult=true"
for /f "tokens=1 delims=1234567890%~3" %%n in ("%~2") do set xResult=false
endlocal & if not "%~1"=="" set "%~1=%xResult%"
goto :eof
:: Usage Example.
:: The variable xResult will be set to true if %%~nxA is a decimal number.
call :IsNumber xResult "%%~nxA" "."

Copying files based on date modified in batch file

I am trying to copy files from one directory to another using a DOS batch script. The files I want to copy are the 4 or 3 latest files. That number will be static, but yet to be determined. Is there anyway to copy based on date modified?
Thank you
You could:
1) have the dir command sort files in the descending order of date modified;
2) use the output of the dir command in a `for loop to copy the corresponding files;
3) count to 3 (or 4) in the for loop to limit the number of files copied.
#ECHO OFF
SET "srcdir=D:\Source"
SET "tgtdir=D:\Target"
SET /A topcnt=3
SET /A cnt=0
FOR /F "tokens=*" %%F IN ('DIR /A-D /OD /TW /B "%srcdir%"') DO (
SET /A cnt+=1
SETLOCAL EnableDelayedExpansion
IF !cnt! GTR !topcnt! (ENDLOCAL & GOTO :EOF)
ENDLOCAL
COPY "%srcdir%\%%F" "%tgtdir%"
)