1

Тема: CMD/BAT: Плановое создание архивной копии SQL баз

Очень часто нужно ставить на архивирование базы в SQL. Обычно я пользуюсь следующим скриптом в планировщике:

@ECHO OFF
COLOR 0A

:: этот скрипт предназначен для выгрузки баз из SQL
:: и архивации выгруженных баз архиватором 7zip
:: для работы нужен архиватор 7zip

:: указываем временный каталог(tmpcat), каталог для архивов(arhcat),
:: пользователя для SQL(SQLuser), пароль для пользователя SQL(SQLpassword)
:: и имя сервера SQL(SQLserver)
set tmpcat=E:\Sql backup\tmpcat
set arhcat=E:\Sql backup
set SQLserver=testserver\sqlexpress2008
set SQLuser=sa
set SQLpassword=hsdgfdf34

:: создаем запись о дате начала скрипта в логе
echo -------------- %date%  %time% -------------- >> "log.txt"

:: проверяем наличие директории arhcat
if not exist "%arhcat%" md "%arhcat%"
if not exist "%arhcat%" (
    echo ЌҐв ¤®бвгЇ  Є Ї ЇЄҐ "%arhcat%"
    echo Нет доступа к папке "%arhcat%" >> "log.txt"
    pause>nul
    goto :EOF
) else (
    echo Џ®ЁбЄ Ї ЇЄЁ "%arhcat%" ... ­ ©¤Ґ­ 
    echo Поиск папки "%arhcat%" ... найдена >> "log.txt"
)
echo Тест на запись в папку %arhcat% > "%arhcat%\testfile.txt"
if not exist "%arhcat%\testfile.txt" (
    echo ЌҐв ¤®бвгЇ  ­  § ЇЁбм Є Ї ЇЄҐ "%arhcat%"
    echo Нет доступа на запись к папке "%arhcat%" >> "log.txt"
    pause>nul
    goto :EOF
) else (
    del /F /Q "%arhcat%\testfile.txt"
    echo „®бвгЇ ­  § ЇЁбм ў Ї ЇЄг "%arhcat%" ... Ґбвм
    echo Доступ на запись к папке "%arhcat%" ... есть >> "log.txt"
)

:: проверяем наличие директории tmpcat
if not exist "%tmpcat%" md "%tmpcat%"
if not exist "%tmpcat%" (
    echo ЌҐв ¤®бвгЇ  Є Ї ЇЄҐ "%tmpcat%"
    echo Нет доступа к папке "%tmpcat%" >> "log.txt"
    pause>nul
    goto :EOF
) else (
    echo Џ®ЁбЄ Ї ЇЄЁ "%tmpcat%" ... ­ ©¤Ґ­ 
    echo Поиск папки "%tmpcat%" ... найдена >> "log.txt"
)
echo test to write in directory %tmpcat% > "%tmpcat%\testfile.txt"
if not exist "%tmpcat%\testfile.txt" (
    echo ЌҐв ¤®бвгЇ  ­  § ЇЁбм Є Ї ЇЄҐ "%tmpcat%"
    echo Нет доступа на запись к папке "%tmpcat%" >> "log.txt"
    pause>nul
    goto :EOF
) else (
    del /F /Q "%tmpcat%\testfile.txt"
    echo „®бвгЇ ­  § ЇЁбм Є Ї ЇЄҐ "%tmpcat%" ... Ґбвм
    echo Доступ на запись к папке "%tmpcat%" ... есть >> "log.txt"
)

:: очищаем временную директорию
del /F /Q "%tmpcat%\*.*"

:: проверяем наличие архиватора
if exist "%programfiles%\7-zip\7z.exe" set "zp_path=%programfiles%\7-zip"
if exist "%programfiles(x86)%\7-zip\7z.exe" set "zp_path=%programfiles(x86)%\7-zip"
if not exist "%zp_path%\7z.exe" if exist %windir%\system32\7z.exe set zp_path=%windir%\system32
if not exist "%zp_path%\7z.exe" if exist %arhcat%\7z.exe set zp_path=%arhcat%
if not exist "%zp_path%\7z.exe" if exist 7z.exe set "zp_path=%~dp0"
if not exist "%zp_path%\7z.exe" if exist 7z.exe set zp_path=%zp_path:~0,-1%
if not exist "%zp_path%\7z.exe" for /f "Usebackq Tokens=1 delims=," %%I in (`dir %systemdrive%\7z.exe /o:-s/s/p/b`) do set zp_path=%%~dpI
set last_char=%zp_path:~-1%
if "%last_char%"=="\" set zp_path=%zp_path:~0,-1%
if not exist "%zp_path%\7z.exe" (
    echo ЌҐ ­ ©¤Ґ­  аеЁў в®а 7z
    echo Не найден архиватор 7z >> "log.txt"
    pause>nul
    goto :EOF
)
echo ЂаеЁў в®а 7z ­ ©¤Ґ­ ў Ї ЇЄҐ "%zp_path%"
echo Архиватор 7z найден в папке "%zp_path%" >> "log.txt"

:: создаём скрипт для получения списка баз на SQL сервере
echo ‘®§¤ Ґ¬ бЄаЁЇв ¤«п Ї®«г祭Ёп бЇЁбЄ  Ў § ­  SQL бҐаўҐаҐ
echo Создаем скрипт для получения списка баз на SQL сервере >> "log.txt"
echo declare @version varchar(14)>"%tmpcat%\getnamebases.sql"
echo select @version = cast(serverproperty('ProductVersion') as varchar(14))>>"%tmpcat%\getnamebases.sql"
echo if substring(@version, 1, charindex('.', @version) - 1) ^>= 9 >>"%tmpcat%\getnamebases.sql"
echo select name from sys.databases>>"%tmpcat%\getnamebases.sql"
echo else select name from sysdatabases>>"%tmpcat%\getnamebases.sql"

:: получаем список баз на SQL сервере в файл namebases.txt
echo Џ®«гз Ґ¬ бЇЁб®Є Ў § ­  SQL бҐаўҐаҐ ў д ©« "%tmpcat%\namebases.txt"
echo Получаем список баз на SQL сервере в файл "%tmpcat%\namebases.txt" >> "log.txt"
sqlcmd -S %SQLserver% -U %SQLuser% -P %SQLpassword% -i "%tmpcat%\getnamebases.sql">"%tmpcat%\namebases.txt"
if /i %errorlevel% geq 1 (
    echo ЌҐв ¤®бвгЇ  Є SQL бҐаўҐаг "%SQLserver%"
    echo Нет доступа к SQL серверу "%SQLserver%" >> "log.txt"
    pause>nul
    goto :EOF
)

:: удаляем старый скрипт если он есть
if exist "%tmpcat%\getnamebases.sql" del /F /Q "%tmpcat%\getnamebases.sql"

:: составляем список баз для архивирования без системных баз
findstr /i /v "( master name tempdb model msdb ReportServer ReportServerTempDB -" "%tmpcat%\namebases.txt" > "%tmpcat%\namebasesreal.txt"

:: удаляем старый список баз если он есть
if exist "%tmpcat%\namebases.txt" del /F /Q "%tmpcat%\namebases.txt"

:: запускаем цикл перебора из файла со списком баз SQL
for /f "usebackq tokens=1 delims=," %%I in ("%tmpcat%\namebasesreal.txt") do Call :realnamebases %%I

:realnamebases

:: задаем наименования баз которые будут игнорироваться при переборе
if "%1"=="" goto :EOF
if "%1"==" " goto :EOF

:: создаём скрипт с именем %1 нужной базы для выгрузки из SQL
echo ‘®§¤ Ґ¬ бЄаЁЇв ¤«п ўлЈаг§ЄЁ Ў §л "%1"
echo Создаем скрипт для выгрузки базы "%1" >> "log.txt"
echo DECLARE @pathName NVARCHAR(512)>"%tmpcat%\%1.sql"
echo SET @pathName = '%tmpcat%\%1.bak'>>"%tmpcat%\%1.sql"
echo BACKUP DATABASE [%1] TO DISK = @pathName WITH NOFORMAT, NOINIT, NAME = N'db_backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10>>"%tmpcat%\%1.sql"

:: получаем в переменные текущие дату и день
set data=%date:~3,7%
set day=%date:~0,5%
set "mytime=%time:~0,-9%.%time:~3,2%"

:: запускаем в SQL скрипт для выгрузки базы
echo ‡ ЇгбЄ Ґ¬ ўлЈаг§Єг Ў §л "%1"
echo Запускаем выгрузку базы "%1" >> "log.txt"
sqlcmd -S %SQLserver% -U %SQLuser% -P %SQLpassword% -i "%tmpcat%\%1.sql"
if /i %errorlevel% geq 1 (
    echo ЌҐв ¤®бвгЇ  Є SQL бҐаўҐаг "%SQLserver%"
    echo Нет доступа к SQL серверу "%SQLserver%" >> "log.txt"
    pause>nul
    goto :EOF
)

:: проверяем наличие старого архива, если есть удаляем его
if exist "%arhcat%\%1\%1.7z" DEL /F /Q "%arhcat%\%1\%1.7z"

:: проверяем наличие директории для архива
if not exist "%arhcat%\%1\%data%" md "%arhcat%\%1\%data%"

:: запускаем архивацию выгруженной базы SQL средствами 7zip
echo ‡ ЇгбЄ Ґ¬  аеЁў жЁо Ў §л "%1"
echo Запускаем архивацию базы "%1" >> "log.txt"
"%zp_path%\7z.exe" a -t7z "%arhcat%\%1\%1.7z" "%tmpcat%\%1.bak" -m0=LZMA:d26 -ms -mmt

:: копируем архив базы в папку для этой базы
copy /Y "%arhcat%\%1\%1.7z" "%arhcat%\%1\%data%\%1_%day%_%mytime%.7z"

:: проверяем наличие архива, если есть удаляем его
if exist "%arhcat%\%1\%1.7z" DEL /F /Q "%arhcat%\%1\%1.7z"

:: очищаем временную директорию
if exist "%tmpcat%\%1.bak" DEL /F /Q "%tmpcat%\%1.bak"
if exist "%tmpcat%\%1.sql" DEL /F /Q "%tmpcat%\%1.sql"

Не судите строго если где корявая реализация, а лучше укажите на ошибки.