Comment afficher la progression dans un file batch en utilisant sqlcmd?

Je fais une sauvegarde d'une grande database dans un file de commands DOS (pas PowerShell), en utilisant sqlcmd ( reference sqlcmd ). Cela prend environ 30 minutes.

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" 

Si vous exécutez la command BACKUP dans SQL Management Studio, vous obtenez la sortie, comme cela arrive:

 10 percent processed. 20 percent processed. ... 

Dans un lot DOS, au mieux, je reçois tous les 10,20,30..100 tous apparaître sur l'écran à la fois, lorsque la sauvegarde est terminée.

J'ai essayé de jouer avec ces parameters, mais je n'obtiens toujours pas la mise à jour de progrès souhaitée à l'écran:

 -m-1 -V 1 -r1 

Ces messages de progression sont mis en memory tampon, ce qui peut faire partie du problème. Ceci est décrit ici par exemple: Comment vider le tampon PRINT dans TSQL? Mais j'ai une seule command longue, pas plusieurs commands.

Vous pouvez exécuter une instruction SQL distincte ailleurs, et cela vous indique la progression et même l'heure de fin estimée:

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

Mais pour l'utiliser, je devrais créer un deuxième file batch (avec sqlcmd exécutant cette instruction), le faire ouvrir dans une nouvelle window juste avant d'exécuter la sauvegarde sqlcmd, et l'exécuter en boucle sur une timer de 1 minute peut-être, et terminez-le lorsque la sauvegarde est terminée. Tout ça en batch. Idéalement, je préfère garder tout cela dans un seul file batch! Sortie des messages de progrès standard serait beaucoup plus simple!

Des idées?

J'ai trouvé une sorte de solution. L'inconvénient est qu'il implique un second file batch. Il lance essentiellement une window de progression avec un nom donné. Cette window de progression se rafraîchit régulièrement. Une fois le process principal terminé, il appelle taskkill utilisant le nom donné. Le lot de progression dépend du timeout d' timeout . Les deux sont sur mon post de travail Windows 8 et 2008 R2 et 2012 servers.

Lot de sauvegarde principal:

 @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 

Fichier batch de progression (appelé backup_progress2.cmd dans le lot principal). Les setlocal enableextensions enabledelayedexpansion sont juste pour que je puisse afficher l'heure avec des secondes en utilisant !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