如何使用 sqlcmd 在批处理文件中显示进度?
How to show progress in a batch file using sqlcmd?
我正在使用 sqlcmd (sqlcmd reference) 在 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
这些进度消息已缓冲,这可能是问题的一部分。例如,这在这里讨论:How do I flush the PRINT buffer in TSQL?
但是我只有一个长 运行ning 命令,而不是多个命令。
您可以在别处 运行 单独的 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),使其在新的 window 中打开,就在 运行ning sqlcmd 备份之前, 运行 它可能会在 1 分钟的计时器上循环,并在备份完成后结束。所有这些都是批量的。理想情况下,我宁愿将其全部保存在一个批处理文件中!输出标准进度消息会简单得多!
有什么想法吗?
我想出了一种解决方案。缺点是它涉及第二个批处理文件。它基本上启动了一个具有给定名称的进度 window。此进度 window 定期刷新。主进程完成后,它会使用给定的名称调用 taskkill
。进度批次依赖timeout
。两者都在我的 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_progress2.cmd
)。 setlocal enableextensions enabledelayedexpansion
只是为了让我可以使用 !time!
.
以秒为单位显示时间
@echo off
rem
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 (sqlcmd reference) 在 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
这些进度消息已缓冲,这可能是问题的一部分。例如,这在这里讨论:How do I flush the PRINT buffer in TSQL? 但是我只有一个长 运行ning 命令,而不是多个命令。
您可以在别处 运行 单独的 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),使其在新的 window 中打开,就在 运行ning sqlcmd 备份之前, 运行 它可能会在 1 分钟的计时器上循环,并在备份完成后结束。所有这些都是批量的。理想情况下,我宁愿将其全部保存在一个批处理文件中!输出标准进度消息会简单得多!
有什么想法吗?
我想出了一种解决方案。缺点是它涉及第二个批处理文件。它基本上启动了一个具有给定名称的进度 window。此进度 window 定期刷新。主进程完成后,它会使用给定的名称调用 taskkill
。进度批次依赖timeout
。两者都在我的 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_progress2.cmd
)。 setlocal enableextensions enabledelayedexpansion
只是为了让我可以使用 !time!
.
@echo off
rem
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