2015-07-07 22 views
6

sqlcmd (sqlcmd reference) kullanarak büyük bir veritabanının bir dos toplu iş dosyasında (powershell değil) bir yedeğini yapıyorum. Yaklaşık 30 dakika sürüyor. SQL Management Studio'da YEDEK komutunu çalıştırırsanız o olurBir toplu iş dosyasında ilerleme sqlcmd kullanarak nasıl gösterilir?

sqlcmd -S 127.0.0.1 -d DbNameHere -E -Q "BACKUP DATABASE [DbNameHere] TO DISK = N'c:\Temp\MyBackup.bak' WITH COPY_ONLY, NOFORMAT, INIT, NAME = N'My Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10" 

, sen çıktı alın:

10 percent processed. 
20 percent processed. 
... 

bir DOS toplu olarak, en iyi ihtimalle, bütün 10,20 olsun, 30..100 hepsi, yedekleme bittiğinde ekranda bir defada görünür.

Ben bu parametrelerle oynayarak denedim, ama yine de ekranda istenilen ilerleme güncelleme alamadım:

-m-1 
-V 1 
-r1 

Bu ilerleme mesajları tamponlu edilir ve bu sorunun bir parçası olabilir. Bu, örneğin burada dicsussed: How do I flush the PRINT buffer in TSQL? Ama birden çok komut değil, tek bir uzun koşma komutum var.

Başka bir yerde ayrı bir SQL deyimi çalıştırabilir ve bu size ilerleme ve hatta tahmin bitmiş zaman söyler: Bir ile

SELECT session_id as SPID, command, a.text AS Query, start_time, percent_complete, dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time 
FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a 
WHERE r.command in ('BACKUP DATABASE','RESTORE DATABASE') 

Ama bu kullanmak için ikinci bir toplu iş dosyası oluşturmak gerekir (sqlcmd bu ifadeyi yürütürken, sqlcmd yedeklemesini çalıştırmadan hemen önce yeni bir pencerede açabilir ve 1 dakikalık zamanlayıcısında bir döngüde çalıştırabilir ve yedekleme bittiğinde sona erdirebilir. Tüm bu partilerde. İdeal olarak, hepsini tek bir toplu iş dosyasında tutmayı tercih ederim! Standart ilerleme mesajlarının çıkması çok daha kolay olurdu!

Herhangi bir fikrin var mı?

+0

"sqlcmd-S 127.0.0.1" işlevini çalıştırdıktan sonra, komutları etkileşimli olarak yazarsanız, bu işlem hemen gösterilir mi? – wOxxOm

+0

wOxxOm, "sqlcmd -S 127.0.0.1" yi etkileşimli olarak çalıştırırsam, '1 '' sonra yedekleme komutunu yazarım,' '' '' '' '' '' '' '' '' '' '' 'yazıp' [return] 'yazdıktan sonra, ilerleme Bu olur, tüm yedekleme deyiminin tamamlanmasından sonra hepsi bir arada görüntülenir. –

cevap

1

Bir çeşit çözüm buldum. Dezavantajı ikinci bir batchfile gerektirir. Temelde belirli bir adla bir ilerleme penceresi başlatır. Bu ilerleme penceresi düzenli olarak yenilenir. Ana işlem bittiğinde, verilen adı kullanarak taskkill'u çağırır. İlerleme durumu timeout'a dayanır. Her ikisi de Windows 8 iş istasyonumda ve 2008 R2 ve 2012 sunucularında.

Ana yedekleme toplu: (ana toplu backup_progress2.cmd denir)

@echo off 
rem lots of other lines in my main batch file here 

start "BACKUP_PROGRESS" /belownormal cmd /d /c "backup_progress2.cmd" 

sqlcmd -S 127.0.0.1 -d DBNameHere-E -Q "BACKUP DATABASE [DBNameHere] TO DISK = N'c:\Temp\DBNameHere.bak' WITH COPY_ONLY, NOFORMAT, INIT, NAME = N'DBNameHere-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10" 

taskkill /FI "WINDOWTITLE eq BACKUP_PROGRESS" /F > nul 

rem my main batch file continues here with lots of other lines 

İlerleme toplu iş dosyası. setlocal enableextensions enabledelayedexpansion sadece !time! kullanarak zamanı saniyelerle görüntüleyebilmem için.

@echo off 
rem http://stackoverflow.com/questions/21434982/windows-batch-scripting-catch-user-reaction-to-timeout-command 
SET timeout=60 

:loop 
cls 
setlocal enableextensions enabledelayedexpansion 
echo. 
echo Time now: !time! 
echo. 
endlocal 
sqlcmd -S 127.0.0.1 -d DBNameHere -E -Q "SET NOCOUNT ON;SELECT start_time,cast(percent_complete as int) as progress,dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time, cast(estimated_completion_time/1000/60 as int) as minutes_left FROM sys.dm_exec_requests r WHERE r.command='BACKUP DATABASE'" 
echo. 
echo Refreshing every %timeout% seconds. 
timeout %timeout% > nul 
goto loop