2015-07-07 28 views
6

Sto facendo un backup di un grande database in un file batch dos (non powershell), usando sqlcmd (sqlcmd reference). Ci vogliono circa 30 minuti.Come mostrare i progressi in un file batch usando sqlcmd?

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" 

Se si esegue il comando BACKUP in SQL Management Studio, si ottiene l'output, come accade:

10 percent processed. 
20 percent processed. 
... 

In un batch DOS, nella migliore delle ipotesi, ho tutte le 10,20, 30..100 tutti visualizzati sullo schermo contemporaneamente, una volta completato il backup.

ho provato a giocare con questi parametri, ma ancora non si ottiene l'aggiornamento di avanzamento desiderata sullo schermo:

-m-1 
-V 1 
-r1 

Questi messaggi di avanzamento sono tamponati, e che potrebbe essere parte del problema. Questo è dicsussed qui per esempio: How do I flush the PRINT buffer in TSQL? Ma ho un unico comando a lunga esecuzione, non più comandi.

È possibile eseguire un'istruzione SQL separata altrove, e che ti dice il progresso e anche il tempo finito stimato:

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') 

Ma da usare che, avrei dovuto creare un secondo file batch (con un sqlcmd che esegue questa istruzione), lo apre in una nuova finestra poco prima di eseguire il backup sqlcmd e lo esegue in un ciclo su un timer di 1 minuto, magari, e termina quando il backup è terminato. Tutto in gruppo. Idealmente, preferirei conservare tutto in un unico file batch! L'output dei messaggi di avanzamento standard sarebbe molto più semplice!

Qualche idea?

+0

Mostra l'avanzamento immediatamente se si digitano i comandi in modo interattivo dopo l'esecuzione di 'sqlcmd -S 127.0.0.1'? – wOxxOm

+0

wOxxOm, se corro correntemente 'sqlcmd -S 127.0.0.1', dopo' 1> 'Digito il comando backup, dopo' 2> 'I digita' GO' quindi '[return]', il progresso non viene mostrato come succede, è tutto visualizzato in un colpo solo dopo il completamento dell'intera istruzione di backup. –

risposta

1

Mi è venuta in mente una soluzione. Il rovescio della medaglia è che coinvolge un secondo batchfile. Fondamentalmente lancia una finestra di avanzamento con un nome specifico. Questa finestra di avanzamento si aggiorna regolarmente. Una volta terminato il processo principale, chiama taskkill utilizzando il nome specificato. Il lotto di avanzamento si basa su timeout. Entrambi sono sulla mia workstation Windows 8 e sui server 2008 R2 e 2012.

principale gruppo di backup:

@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 

file batch Progress (chiamato backup_progress2.cmd nel lotto principale). Il setlocal enableextensions enabledelayedexpansion è solo così che posso visualizzare l'ora in secondi usando !time!.

@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