Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 轮询SSIS执行状态_C#_Ssis_Sql Server 2014 - Fatal编程技术网

C# 轮询SSIS执行状态

C# 轮询SSIS执行状态,c#,ssis,sql-server-2014,C#,Ssis,Sql Server 2014,我有一个SSIS包,它正在Foreach容器中启动另一个SSIS包;因为容器在启动它必须启动的所有包时就报告完成,所以我需要一种方法使它等待所有“子”包完成 因此,我实现了一个小的sleep wait循环,它基本上将我感兴趣的ID的执行对象从SSISDB中拉出来 我面临的问题是,总共有0个Dts.Events.FireProgress事件被触发,如果我在do循环中取消对Dts.Events.FireInformation调用的注释,那么每秒我都会收到一条消息,报告说23个包仍在运行。。。除非我签

我有一个SSIS包,它正在Foreach容器中启动另一个SSIS包;因为容器在启动它必须启动的所有包时就报告完成,所以我需要一种方法使它等待所有“子”包完成

因此,我实现了一个小的sleep wait循环,它基本上将我感兴趣的ID的
执行
对象从SSISDB中拉出来

我面临的问题是,总共有0个
Dts.Events.FireProgress
事件被触发,如果我在
do
循环中取消对
Dts.Events.FireInformation
调用的注释,那么每秒我都会收到一条消息,报告说23个包仍在运行。。。除非我签入SSIDB的活动操作窗口,否则我会看到大多数操作已经完成,3或4个操作实际上正在运行

我做错了什么,为什么
runningCount
不包含实际运行的执行数

using ssis = Microsoft.SqlServer.Management.IntegrationServices;

public void Main()
{
    const string serverName = "REDACTED";
    const string catalogName = "SSISDB";

    var ssisConnectionString = $"Data Source={serverName};Initial Catalog=msdb;Integrated Security=SSPI;";
    var ids = GetExecutionIDs(serverName);

    var idCount = ids.Count();
    var previousCount = -1;

    var iterations = 0;

    try
    {
        var fireAgain = true;

        const int secondsToSleep = 1;
        var sleepTime = TimeSpan.FromSeconds(secondsToSleep);
        var maxIterations = TimeSpan.FromHours(1).TotalSeconds / sleepTime.TotalSeconds;

        IDictionary<long, ssis.Operation.ServerOperationStatus> catalogExecutions;
        using (var connection = new SqlConnection(ssisConnectionString))
        {
            var server = new ssis.IntegrationServices(connection);
            var catalog = server.Catalogs[catalogName];
            do
            {
                catalogExecutions = catalog.Executions
                    .Where(execution => ids.Contains(execution.Id))
                    .ToDictionary(execution => execution.Id, execution => execution.Status);

                var runningCount = catalogExecutions.Count(kvp => kvp.Value == ssis.Operation.ServerOperationStatus.Running);
                System.Threading.Thread.Sleep(sleepTime);

                //Dts.Events.FireInformation(0, "ScriptMain", $"{runningCount} packages still running.", string.Empty, 0, ref fireAgain);

                if (runningCount != previousCount)
                {
                    previousCount = runningCount;
                    decimal completed = idCount - runningCount;
                    decimal percentCompleted = completed / idCount;
                    Dts.Events.FireProgress($"Waiting... {completed}/{idCount} completed", Convert.ToInt32(100 * percentCompleted), 0, 0, "", ref fireAgain);
                }

                iterations++;
                if (iterations >= maxIterations)
                {
                    Dts.Events.FireWarning(0, "ScriptMain", $"Timeout expired, requesting cancellation.", string.Empty, 0);
                    Dts.Events.FireQueryCancel();
                    Dts.TaskResult = (int)Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Canceled;
                    return;
                }
            }
            while (catalogExecutions.Any(kvp => kvp.Value == ssis.Operation.ServerOperationStatus.Running));
        }
    }
    catch (Exception exception)
    {
        if (exception.InnerException != null)
        {
            Dts.Events.FireError(0, "ScriptMain", exception.InnerException.ToString(), string.Empty, 0);
        }
        Dts.Events.FireError(0, "ScriptMain", exception.ToString(), string.Empty, 0);
        Dts.Log(exception.ToString(), 0, new byte[0]);
        Dts.TaskResult = (int)ScriptResults.Failure;
        return;
    }

    Dts.TaskResult = (int)ScriptResults.Success;
}
使用ssis=Microsoft.SqlServer.Management.IntegrationServices;
公共图书馆
{
常量字符串serverName=“已编辑”;
常量字符串catalogName=“SSISDB”;
var ssinconnectionstring=$“数据源={serverName};初始目录=msdb;集成安全性=SSPI;”;
var id=getExecutionId(服务器名);
var idCount=ids.Count();
var previousCount=-1;
var迭代次数=0;
尝试
{
var=true;
const int secondsToSleep=1;
var sleepTime=TimeSpan.FromSeconds(secondsToSleep);
var maxIterations=TimeSpan.FromHours(1).TotalSeconds/sleepTime.TotalSeconds;
词典目录;
使用(var连接=新的SqlConnection(ssisConnectionString))
{
var服务器=新ssis.IntegrationServices(连接);
var catalog=server.Catalogs[catalogName];
做
{
catalogExecutions=catalog.Executions
.Where(execution=>ids.Contains(execution.Id))
.ToDictionary(execution=>execution.Id,execution=>execution.Status);
var runningCount=catalogExecutions.Count(kvp=>kvp.Value==ssis.Operation.ServerOperationStatus.Running);
系统。线程。线程。睡眠(睡眠时间);
//FireInformation(0,“ScriptMain”,$“{runningCount}包仍在运行。”,string.Empty,0,再次引用FireInformation);
if(runningCount!=上一次计数)
{
previousCount=运行计数;
十进制完成=idCount-runningCount;
小数百分比完成=完成/idCount;
Dts.Events.FireProgress($“Waiting…{completed}/{idCount}completed”,Convert.ToInt32(100*percentCompleted),0,0,”,再次引用FireProgress);
}
迭代++;
如果(迭代次数>=最大迭代次数)
{
Dts.Events.FireWarning(0,“ScriptMain”,“超时已过期,请求取消)”,string.Empty,0);
FireQueryCancel();
Dts.TaskResult=(int)Microsoft.SqlServer.Dts.Runtime.dtsesecresult.cancelled;
返回;
}
}
while(catalogExecutions.Any(kvp=>kvp.Value==ssis.Operation.ServerOperationStatus.Running));
}
}
捕获(异常)
{
if(exception.InnerException!=null)
{
FireError(0,“ScriptMain”,exception.InnerException.ToString(),string.Empty,0);
}
Dts.Events.FireError(0,“ScriptMain”,exception.ToString(),string.Empty,0);
Log(exception.ToString(),0,新字节[0]);
Dts.TaskResult=(int)ScriptResults.Failure;
返回;
}
Dts.TaskResult=(int)ScriptResults.Success;
}

getExecutionId
函数只是从我的元数据数据库中返回子包的所有执行ID。

问题在于每次迭代都使用相同的连接。把这个翻过来:

为此:

do
{
    using (var connection = new SqlConnection(ssisConnectionString))
    {
        var server = new ssis.IntegrationServices(connection);
        var catalog = server.Catalogs[catalogName];
        catalogExecutions = catalog.Executions
            .Where(execution => ids.Contains(execution.Id))
            .ToDictionary(execution => execution.Id, execution => execution.Status);
    }

每次都会得到正确的执行状态。不知道为什么连接不能被重用,但保持连接尽可能短的寿命始终是一个好主意,这是另一个证明。

我没有在SSIS中使用
c#
,但是你不能
c#
中执行
包吗?这样,您就可以在继续处理之前返回一个结果。@NickyvV foreach循环正在迭代元数据行,以确定使用什么参数化包-我正在循环中运行同一个包的20多个实例,并且需要它们同时运行(该部分工作)。问题是,如果我不做任何事情,那么“主”包在“子”包完成运行之前报告完成,而我不能这样做;上面是一个脚本任务,它遵循foreach容器,基本上等待所有“子”包完成。我不能让
execute
成为一个阻塞调用,因为我需要它们是并发的。此外,出于某种原因,我不能在该脚本中的任何地方中断—我的意思是我可以放置断点,但它们从未被命中,尽管SSIS控制流在脚本任务框中显示了红点。
do
{
    using (var connection = new SqlConnection(ssisConnectionString))
    {
        var server = new ssis.IntegrationServices(connection);
        var catalog = server.Catalogs[catalogName];
        catalogExecutions = catalog.Executions
            .Where(execution => ids.Contains(execution.Id))
            .ToDictionary(execution => execution.Id, execution => execution.Status);
    }