我正在编写一个 Powershell 脚本,它对本地 SQL Server 数据库执行几项操作。
我正在做的一件事是一个接一个地运行多个 SQL 作业。我像这样运行它们:
sqlcmd -S .\ -Q "EXECUTE msdb.dbo.sp_start_job @job_name = 'Rebuild Content Asset Relationship Data'"
有没有办法让 Powershell 延迟运行下一个作业,直到第一个作业完成?
谢谢
我正在编写一个 Powershell 脚本,它对本地 SQL Server 数据库执行几项操作。
我正在做的一件事是一个接一个地运行多个 SQL 作业。我像这样运行它们:
sqlcmd -S .\ -Q "EXECUTE msdb.dbo.sp_start_job @job_name = 'Rebuild Content Asset Relationship Data'"
有没有办法让 Powershell 延迟运行下一个作业,直到第一个作业完成?
谢谢
要从 PowerShell 访问 SQL 代理作业,您可以使用 SMO:
编辑:如果您要将此功能添加到您的脚本中,考虑到效率,我会将 SMO 加载出来并将其放置在您的脚本顶部附近(在此功能之前)。如果每次调用该函数时它都会重新加载程序集,它可能会减慢您的脚本速度。
Function Get-SQLJobStatus
{
param ([string]$server, [string]$JobName)
# Load SMO assembly, and if we're running SQL 2008 DLLs load the SMOExtended and SQLWMIManagement libraries
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
# Create object to connect to SQL Instance
$srv = New-Object "Microsoft.SqlServer.Management.Smo.Server" $server
# used to allow piping of more than one job name to function
if($JobName)
{
foreach($j in $jobName)
{
$srv.JobServer.Jobs | where {$_.Name -match $JobName} | Select Name, CurrentRunStatus
}
}
else #display all jobs for the instance
{
$srv.JobServer.Jobs | Select Name, CurrentRunStatus
} #end of Get-SQLJobStatus
}
您可以使用此功能的方式示例:
#will display all jobs on the instance
Get-SQLJobStatus MyServer
#pipe in more than one job to get status
"myJob","myJob2" | foreach {Get-SQLJobStatus -Server MyServer -JobName $_}
#get status of one job
Get-SQLJobStatus -Server MyServer -JobName "MyJob"
你可以在你的脚本中使用这个函数,然后在一个while循环或其他东西中重复调用它,直到你的工作状态显示“空闲”。至少在我看来这是我认为可行的:)
当然,Start-Sleep -seconds <nn>
在 sqlcmd.exe 的调用之间执行一次。
我的建议是将您的工作包装在一个新的存储过程中,该存储过程启动该工作,然后通过不断轮询其状态来等待它完成。从随附的文章中,您可以执行以下操作:
DECLARE @JobStatus INT
SET @JobStatus = 0
EXEC MSDB.dbo.sp_start_job @Job_Name = 'JobName'
SELECT @JobStatus = current_execution_status FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;',
'EXEC MSDB.dbo.sp_help_job @job_name = ''JobName'', @job_aspect = ''JOB'' ')
WHILE @JobStatus <> 4
BEGIN
SELECT @JobStatus = current_execution_status FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;',
'EXEC MSDB.dbo.sp_help_job @job_name = ''JobName'', @job_aspect = ''JOB'' ')
END
然后,不是从命令行调用,而是sp_start_job
从命令行调用您的 sproc,PowerShell 将被阻止,直到该 sproc 完成。希望这可以帮助!
您的作业由 SQL Server 代理执行。您可以直接从您的 PowerShell 脚本调用相应的存储过程(或 SQL 语句),或者您在此处解释的行中实现某些内容。