windows下 sql 自動備份腳本

公司的環境是win2003r2 64位加 mssql2005.
數據天天都要備份。
剛開始用的是mssql自帶的排程備份功能。感受不太好用。(出現過恢復失敗的狀況)
就寫了如下腳本作計劃任務備份。供你們參考。

@Echo %date% %time% DEBUG ********** 開始執行 **********
@set NowTime=%time%
@echo off
Rem 1. 產生命令檔 %SQLFILE% (Generate %SQLFILE%)
Rem 2. 執行命令檔 %SQLFILE% (Execute %SQLFILE%)
Echo %date% %time% DEBUG *** 執行身份 %USERDOMAIN%\%USERNAME%
Echo %date% %time% DEBUG *** 執行命令 %*
:_DateStuff
REM **********
REM *** 日期分割
REM **********
Echo %date% %time% DEBUG *** 日期分割 ***
REM 依日期/時間格式進行修改 yy, mm, dd, wd
REM yy=年
REM mm=月
REM dd=日
REM wd=星期
REM dt=年-月-日-星期 (依系統日期格式而定)
REM 注意: date /t 的傳回值會依據 [標準及格式(Standards and Formats)] 的設定值而有所不一樣
REM 若爲English, 則爲 星期 月/日/年
REM 若爲Chinese, 則爲 年/月/日 星期
Rem 偵測日期格式爲 日期+星期 仍是 星期+日期
set CheckNumber=%date:~0,1%
If "%CheckNumber%" == "0" Goto _DateWeekdayAfter
If "%CheckNumber%" == "1" Goto _DateWeekdayAfter
If "%CheckNumber%" == "2" Goto _DateWeekdayAfter
If "%CheckNumber%" == "3" Goto _DateWeekdayAfter
If "%CheckNumber%" == "4" Goto _DateWeekdayAfter
If "%CheckNumber%" == "5" Goto _DateWeekdayAfter
If "%CheckNumber%" == "6" Goto _DateWeekdayAfter
If "%CheckNumber%" == "7" Goto _DateWeekdayAfter
If "%CheckNumber%" == "8" Goto _DateWeekdayAfter
If "%CheckNumber%" == "9" Goto _DateWeekdayAfter
Goto _DateWeekdayBefore
:_DateWeekdayAfter
for /F "tokens=1-4 delims=/ " %%i in ('date /t') do (
  for /f "skip=1 tokens=2-4 delims=/-,()." %%x in ('echo.^|date') do (
   set %%x=%%i
   set %%y=%%j
   set %%z=%%k
  )
  set wd=%%l
)
Goto _DateStuffContinue
:_DateWeekdayBefore
for /F "tokens=1-4 delims=/ " %%i in ('date /t') do (
  set wd=%%i
  for /f "skip=1 tokens=2-4 delims=/-,()." %%x in ('echo.^|date') do (
   set %%x=%%j
   set %%y=%%k
   set %%z=%%l
  )
)
:_DateStuffContinue
Rem 將星期改成英文, 以免亂碼
If "%wd%" == "星期一" set wd=Mon
If "%wd%" == "星期二" set wd=Tue
If "%wd%" == "星期三" set wd=Wed
If "%wd%" == "星期四" set wd=Thu
If "%wd%" == "星期五" set wd=Fri
If "%wd%" == "星期六" set wd=Sat
If "%wd%" == "星期日" set wd=Sun
set dt=%yy%-%mm%-%dd%-%wd%
Echo %date% %time% DEBUG yy=%yy%
Echo %date% %time% DEBUG mm=%mm%
Echo %date% %time% DEBUG dd=%dd%
Echo %date% %time% DEBUG wd=%wd%
Echo %date% %time% DEBUG dt=%dt%
REM **********
REM *** 時間分割
REM **********
Echo %date% %time% DEBUG *** 時間分割 ***
REM hh=時
REM nn=分
REM ss=秒
REM ms=毫秒
REM tm=時-分-秒-毫秒
REM dtt=%dt%-%tm%
rem for /f "Tokens=1-4 Delims=:. " %%i in ("%time%") do (
rem  set hh=%%i
rem  set nn=%%j
rem  set ss=%%k
rem  set ms=%%l
rem )
rem set tm=%hh%-%nn%-%ss%-%ms%
set hh=%NowTime:~0,2%
If "%hh:~0,1%" == " " set hh=0%hh:~1,1%
set nn=%NowTime:~3,2%
set ss=%NowTime:~6,2%
set ms=%NowTime:~9,2%
set tm=%hh%-%nn%-%ss%-%ms%
set dtt=%dt%-%tm%
Echo %date% %time% DEBUG hh=%hh%
Echo %date% %time% DEBUG nn=%nn%
Echo %date% %time% DEBUG ss=%ss%
Echo %date% %time% DEBUG ms=%ms%
Echo %date% %time% DEBUG tm=%tm%
Echo %date% %time% DEBUG dtt=%dtt%
REM **********
REM *** 定義郵件變量
REM **********
Echo %date% %time% DEBUG *** 定義郵件變量 ***
REM blatpath=傳送電子郵件的程序
REM relayserver=電子郵件服務器
REM email=收件者的電子郵件地址
REM fromemail=寄件者的電子郵件地址
REM emailuser=電子郵件服務器的認證使用者
REM emailpass=電子郵件服務器的密碼
set blatpath=C:\blat.exe

set relayserver='你的郵件服務器(要開啓匿名服務哦!)'

if "%COMPUTERNAME%" == "主機名" set email=‘你要接受的郵件的郵箱地址’
set [email=fromemail=MSSQLSERVER@%COMPUTERNAME%.%USERDNSDOMAIN%]fromemail=MSSQLSERVER@%COMPUTERNAME%.%USERDNSDOMAIN%[/email]
set emailuser=
set emailpass=
Echo %date% %time% DEBUG blatpath=%blatpath%
Echo %date% %time% DEBUG relayserver=%relayserver%
Echo %date% %time% DEBUG email=%email%
Echo %date% %time% DEBUG fromemail=%fromemail%
Rem **********
Rem *** 定義SQL變量
Rem **********
Echo %date% %time% DEBUG *** 定義 SQL 變量
Rem SQLFILE=SQL命令檔
Rem BACKUPDIR=備份文件路徑
Rem OUTFILE=執行記錄文件
Rem SERVER=服務器名稱, 預設同%COMPUTER%
Rem USERNAME=登入數據庫的帳號, 預設sa
Rem PASSWORD=登入帳號的密碼
Rem ToDo:
Rem 儘可能不要使用sa帳號, 以避免作錯的話, 影響太大
Set OUTFILE=sql.backup.%dtt%.out.txt
REM ***
REM *** 檢查鎖定檔是否存在 (避免重複執行.)
REM ***
Echo %date% %time% DEBUG *** 檢查是否有鎖定檔, 以免重複執行 ***
set LockFile=sqlcmd.backup.%COMPUTERNAME%.lck.txt
if exist "%LockFile%" goto _isLock
set >> "%LockFile%"
Set SQLFILE=sql.backup.%dtt%.sql.txt
Set BACKUPDIR=‘你要存放備份文件的路徑’

if NOT exist "%BACKUPDIR%" mkdir "%BACKUPDIR%"
Set SERVER=%COMPUTERNAME%
Set USERNAME=‘db 用戶名’
Set PASSWORD=‘db pw’
Set DATABASE=%1
If '%DATABASE%' == '' (
  Goto _BackupAllDatabase
)
Echo %date% %time% DEBUG OUTPUTFILE=%OUTPUTFILE%
Echo %date% %time% DEBUG LockFile=%LockFile%
Echo %date% %time% DEBUG SQLFILE=%SQLFILE%
Echo %date% %time% DEBUG BACKUPDIR=%BACKUPDIR%
Echo %date% %time% DEBUG SERVER=%SERVER%
:_BackupSingleDatabase
Rem **********
Rem *** Backup Single Database
Rem **********
:_BackupSingleDatabaseDifferential
Echo %date% %time% DEBUG *** 產生 BackupSingleDatabaseDifferential 備份命令檔 ***
for %%d in ( %* ) do (
  Echo print '-------------------------------------------------------'     >> %SQLFILE%
  Echo print '1^> backup database [%%d] to disk = ''%BACKUPDIR%\%%d.%dtt%.bak'                         >> %SQLFILE%
  Echo print '2^> go'           >> %SQLFILE%
  Echo go             >> %SQLFILE%
  Echo backup database [%%d] to disk = '%BACKUPDIR%\%%d.%dtt%.bak'                    >> %SQLFILE%
  Echo go             >> %SQLFILE%
  Echo if @@ERROR != 0 print 'Error!'         >> %SQLFILE%
  Echo go             >> %SQLFILE%
  Echo print '1^> backup log [%%d] with truncate_only'       >> %SQLFILE%
  Echo print '2^> go'           >> %SQLFILE%
  Echo go             >> %SQLFILE%
  Echo backup log [%%d] with truncate_only        >> %SQLFILE%
  Echo go             >> %SQLFILE%
  Echo if @@ERROR != 0 print 'Error!'         >> %SQLFILE%
  Echo go             >> %SQLFILE%
  Echo print '1^> dbcc shrinkdatabase ^( ''%%d'', 0, TRUNCATEONLY ^)'     >> %SQLFILE%
  Echo print '2^> go'           >> %SQLFILE%
  Echo go             >> %SQLFILE%
  Echo dbcc shrinkdatabase ^( '%%d', 0, TRUNCATEONLY ^)       >> %SQLFILE%
  Echo go             >> %SQLFILE%
  Echo if @@ERROR != 0 print 'Error!'         >> %SQLFILE%
  Echo go             >> %SQLFILE%
)
Goto _Run
:_BackupAllDatabase
Rem **********
Rem *** Backup All Database
Rem **********
Echo %date% %time% DEBUG *** 產生 BackupAllDatabase 備份命令檔 ***
Echo declare curs1 cursor for select name from master..sysdatabases where name != 'tempdb' and name not like 'bk_^%%' order by 1 >  %SQLFILE%
Echo go             >> %SQLFILE%
Echo declare @dbname   nvarchar(128)         >> %SQLFILE%
Echo declare @filename nvarchar(128)         >> %SQLFILE%
Echo open curs1            >> %SQLFILE%
Echo fetch curs1 into @dbname          >> %SQLFILE%
Echo while @@fetch_status = 0          >> %SQLFILE%
Echo begin            >> %SQLFILE%
Echo  select @filename = '%BACKUPDIR%\' + @dbname + '.%dtt%.bak'     >> %SQLFILE%
Echo  print '-------------------------------------------------------'     >> %SQLFILE%
Echo  print '1^> backup database [' + @dbname + '] to disk = ''' + @filename + ''               >> %SQLFILE%
Echo  print '2^> go'           >> %SQLFILE%
Echo  backup database @dbname to disk = @filename                    >> %SQLFILE%
Rem ECHO  if @@ERROR != 0           >> %SQLFILE%
Rem ECHO  begin            >> %SQLFILE%
Rem ECHO   print '***************'         >> %SQLFILE%
Rem ECHO   print 'Error Occured!!'         >> %SQLFILE%
Rem ECHO   print '***************'         >> %SQLFILE%
Rem ECHO  end            >> %SQLFILE%
Echo  fetch curs1 into @dbname         >> %SQLFILE%
Echo end            >> %SQLFILE%
Echo go             >> %SQLFILE%
Echo close curs1           >> %SQLFILE%
Echo go             >> %SQLFILE%
Echo deallocate curs1                  >> %SQLFILE%
Echo go             >> %SQLFILE%
Goto _Run
:_Run
Rem **********
Rem *** RUN
Rem **********
Type %SQLFILE%
Echo %date% %time% DEBUG *** 正在進行備份 ***
Rem sqlcmd -S %SERVER% -U %username% -P %PASSWORD% -i %SQLFILE% -o %OUTFILE% -w 256
sqlcmd -i %SQLFILE% -o %OUTFILE% -w 256
REM **********
REM *** 搜尋 %OUTFILE% 內的錯誤字符串
REM **********
Echo %date% %time% DEBUG *** 檢查是否有錯誤訊息 ***
REM errmsg=錯誤訊息
SET errmsg=
type "%OUTFILE%" | findstr /i /c:"Msg " > NUL
if %errorlevel% == 0 set errmsg=(ERROR)
type "%OUTFILE%" | findstr /i /c:"failed" > NUL
if %errorlevel% == 0 set errmsg=(ERROR)
type "%OUTFILE%" | findstr /i /c:"Error" > NUL
if %errorlevel% == 0 set errmsg=(ERROR)
type "%OUTFILE%" | findstr /i /c:"異常" > NUL
if %errorlevel% == 0 set errmsg=(ERROR)
REM **********
REM *** 發送電子郵件
REM **********
Echo %date% %time% DEBUG *** 發送電子郵件 ***
REM %blatpath% "%SQLFILE%" -attach "%OUTFILE%" -t %email% -s "%errmsg%%COMPUTERNAME%-%wd%-%backupmode% (%dtt%)" -i %fromemail% -f "%fromemail%" -q -server "%relayserver%" -u "%emailuser%" -pw "%emailpass%" -charset big5
%blatpath% "%OUTFILE%" -attach "%SQLFILE%" -t %email% -s "%errmsg%SQL.Backup.%dtt% (%wd%)" -f "%fromemail%" -server "%relayserver%" -charset big5
if "%errmsg%" == "(ERROR)" %blatpath% "%OUTFILE%" -attach "%SQLFILE%" -t 你的郵箱地址 -s "%errmsg%SQL.Backup.%dtt% (%wd%)" -f "%fromemail%" -server "%relayserver%" -charset big5
Echo %date% %time% DEBUG *** 刪除備份命令檔 ***
DEL %SQLFILE%
Echo %date% %time% DEBUG *** 備份備份結果輸出檔 ***
MOVE "%OUTFILE%" "%BACKUPDIR%"
if "%errmsg%" == "(ERROR)"       Goto _DelLockFile
if "%DATABASE%" == ""            Goto _DelLockFile
Goto _DelLockFile
:_isLock
Echo %date% %time% DEBUG *** %LockFile% 已存在 ***
echo %LockFile% 已存在. >> "%OUTFILE%"
Rem %blatpath% "%OUTFILE%" -attach "%LockFile%" -t %email% -s "(錯誤)%COMPUTERNAME% 已在執行中. %yy%-%mm%-%dd% (%wd%) at %hh%:%nn%:%ss%.%ms%" -i %fromemail% -f "%fromemail%" -q -server "%relayserver%" -u "%emailuser%" -pw "%emailpass%" -charset big5
%blatpath% "%OUTFILE%" -attach "%LockFile%" -t %email% -s "(錯誤)%COMPUTERNAME% 已在執行中. %yy%-%mm%-%dd% (%wd%) at %hh%:%nn%:%ss%.%ms%" -f "%fromemail%" -server "%relayserver%" -charset big5
%blatpath% "%OUTFILE%" -attach "%LockFile%" -t 你的郵箱地址 -s "(錯誤)%COMPUTERNAME% 已在執行中. %yy%-%mm%-%dd% (%wd%) at %hh%:%nn%:%ss%.%ms%" -f "%fromemail%" -server "%relayserver%" -charset big5
goto _End
:_DelLockFile
Echo %date% %time% DEBUG *** 刪除鎖定檔 ***
if Exist "%LockFile%" Del "%LockFile%"
Goto _End
:_End
Echo %date% %time% DEBUG ********** 結束執行 **********

blat.exe 這個郵件發送程序在附件裏面。
腳本中有詳細的註釋。
若有不明請留言。
倉促之間,如有何失誤,還請不吝指教。

 sql

相關文章
相關標籤/搜索