Sql server 如何使用sqlcmd在批处理文件中显示进度?

Sql server 如何使用sqlcmd在批处理文件中显示进度?,sql-server,batch-file,cmd,database-backups,sqlcmd,Sql Server,Batch File,Cmd,Database Backups,Sqlcmd,我正在使用sqlcmd()在dos批处理文件(不是powershell)中备份一个大型数据库。大约需要30分钟 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, NOUNLOA

我正在使用sqlcmd()在dos批处理文件(不是powershell)中备份一个大型数据库。大约需要30分钟

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"
如果在SQL Management Studio中运行BACKUP命令,您将获得输出,具体如下:

10 percent processed.
20 percent processed.
...
在DOS批处理中,当备份完成时,我最多只能同时在屏幕上看到所有的10、20、30..100

我尝试过使用这些参数,但仍然无法在屏幕上获得所需的进度更新:

-m-1
-V 1
-r1
这些进度消息被缓冲,这可能是问题的一部分。这在这里使用,例如: 但是我有一个长时间运行的命令,而不是多个命令

您可以在其他地方运行单独的SQL语句,该语句会告诉您进度甚至估计完成时间:

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')
但要使用它,我必须创建第二个批处理文件(sqlcmd执行此语句),在运行sqlcmd备份之前在新窗口中打开它,并在1分钟的计时器上循环运行它,并在备份完成时结束它。所有这些都是成批的。理想情况下,我宁愿将其全部保存在一个批处理文件中!输出标准进度消息会简单得多


有什么想法吗?

我想出了一种解决办法。缺点是它涉及第二个批处理文件。它基本上会启动一个具有给定名称的进度窗口。此进度窗口将定期刷新。一旦主进程完成,它将使用给定的名称调用
taskkill
。进度批处理依赖于
超时
。它们都在我的Windows 8工作站以及2008 R2和2012服务器上

主备份批处理:

@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
进度批处理文件(在主批处理中称为
backup\u progress2.cmd
)。
setlocal enableextensions enabledelayedexpansion
就是为了让我可以使用
以秒为单位显示时间!时间

@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

如果您在运行
sqlcmd-S 127.0.0.1
之后以交互方式键入命令,它是否立即显示进度?wOxxOm,如果我在
1>之后键入备份命令,在
2>之后键入
GO
然后
[return]
之后以交互方式运行
sqlcmd-S 127.0.0.1
,则显示进度,进度不会按实际情况显示,而是在整个backup语句完成后一次性显示。