用于自动化的SSIS C#脚本任务

用于自动化的SSIS C#脚本任务,c#,ssis,automation,task,C#,Ssis,Automation,Task,我有一个SSIS包,它以一个脚本任务开始,以检查指定目录是否包含三个文件。如果有2个文件,它会打印警告;如果有1个或更少的文件,我会打印错误消息并终止程序。其思想是SQL代理将注册我的包并在指定的时间执行它。但是,我的脚本中必须满足以下条件: switch (numFiles) { case 0: MessageBox.Show("Error: No files are in the director

我有一个SSIS包,它以一个脚本任务开始,以检查指定目录是否包含三个文件。如果有2个文件,它会打印警告;如果有1个或更少的文件,我会打印错误消息并终止程序。其思想是SQL代理将注册我的包并在指定的时间执行它。但是,我的脚本中必须满足以下条件:

switch (numFiles)
            {
                case 0:
                    MessageBox.Show("Error: No files are in the directory C:\\Directory1\n Please restart execution.");
                    break;
                case 1:
                    MessageBox.Show("Error: Only one file was found in the directory C:\\Directory1\n Please restart execution.");
                    break;
                case 2:
                    MessageBox.Show("Warning: Only two files have been loaded into the directory C:\\Directory1\n Is this intended?.");
                    break;
            }
如何优雅地终止程序并打印警告消息?
在服务器上运行时,如何显示此消息?

在服务器上运行时,不能显示这样的消息框

您应该写入日志文件()

要停止从脚本任务运行的包,请使用
RunningPackage.stop
方法

        static void Main(string[] args)
        {
            Application app = new Application();
            RunningPackages pkgs = app.GetRunningPackages("yourserver");

            int pkgsRunning = pkgs.Count;
            Console.WriteLine("Packages before stop: thas + pkgsRunning);

            foreach (RunningPackage p in pkgs)
            {
                Console.WriteLine("InstanceID: " + p.InstanceID);
                Console.WriteLine("PackageDescription: " + p.PackageDescription);
                Console.WriteLine("PackageID: " + p.PackageID);
                Console.WriteLine("PackageName: " + p.PackageName);
                Console.WriteLine("UserName: " + p.UserName);
            }

            pkgs = app.GetRunningPackages("yourserver");
            foreach (RunningPackage package in pkgs)
            {
                package.Stop();
            }

            pkgsRunning = app.GetRunningPackages("yourserver").Count;
            Console.WriteLine("Packages after stop " + pkgsRunning);
        }

我想,你最好还是挂上现有的网络。使用您的代码作为基线,我在包中添加了一个变量,然后部署到SQLServer中

        int numFiles = Convert.ToInt32(Dts.Variables["numFiles"].Value.ToString());
        switch (numFiles)
        {
            case 0:
                //MessageBox.Show("Error: No files are in the directory C:\\Directory1\n Please restart execution.");
                Dts.Events.FireError(0, "File count", "Error: No files are in the directory C:\\Directory1\n Please restart execution.", string.Empty, 0);
                break;
            case 1:
                //MessageBox.Show("Error: Only one file was found in the directory C:\\Directory1\n Please restart execution.");
                Dts.Events.FireError(0, "File count", "Error: Only one file was found in the directory C:\\Directory1\n Please restart execution.", string.Empty, 0);
                break;
            case 2:
                //MessageBox.Show("Warning: Only two files have been loaded into the directory C:\\Directory1\n Is this intended?.");
                Dts.Events.FireWarning(0, "File count", "Warning: Only two files have been loaded into the directory C:\\Directory1\n Is this intended?.", string.Empty, 0);
                break;
        }
从命令行运行

"DTExec.exe" /file /set .\so_RaiseEvents.dtsx /set \Package.Variables[User::numFiles];0

"DTExec.exe" /file /set .\so_RaiseEvents.dtsx /set \Package.Variables[User::numFiles];1

"DTExec.exe" /file /set .\so_RaiseEvents.dtsx /set \Package.Variables[User::numFiles];2
我看到了预期的产出

Error: 2012-08-09 08:53:58.77
   Code: 0x00000000
   Source: Script Task File count
   Description: Error: No files are in the directory C:\Directory1
 Please restart execution.
End Error

Error: 2012-08-09 08:51:56.75
   Code: 0x00000000
   Source: Script Task File count
   Description: Error: Only one file was found in the directory C:\Directory1
 Please restart execution.
End Error

Warning: 2012-08-09 08:51:51.82
   Code: 0x00000000
   Source: Script Task File count
   Description: Warning: Only two files have been loaded into the directory C:\Directory1
 Is this intended?.
End Warning
当您从代理运行时,警告应该显示,但如果没有显示,则需要向报告添加一个参数,以便
/report W

编辑 为了解决这些问题

“如何优雅地终止程序并打印警告消息”FireError将导致脚本任务返回失败代码
Microsoft.SqlServer.Dts.Runtime.dtseSecResult.Success
,从而结束包的执行。警告,如果您想停止包执行,那么您将修改脚本任务以指示它没有成功。为此,我添加了第三个ScriptResult警告枚举,该枚举被转换为.cancelled(唯一一个传达了与计划不符的内容的选项)。完整代码如下

[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{


    /// <summary>
    /// This method is called when this script task executes in the control flow.
    /// Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
    /// To open Help, press F1.
    /// </summary>
    public void Main()
    {
        int numFiles = Convert.ToInt32(Dts.Variables["numFiles"].Value.ToString());
        switch (numFiles)
        {
            case 0:
                //MessageBox.Show("Error: No files are in the directory C:\\Directory1\n Please restart execution.");
                Dts.Events.FireError(0, "File count", "Error: No files are in the directory C:\\Directory1\n Please restart execution.", string.Empty, 0);
                break;
            case 1:
                //MessageBox.Show("Error: Only one file was found in the directory C:\\Directory1\n Please restart execution.");
                Dts.Events.FireError(0, "File count", "Error: Only one file was found in the directory C:\\Directory1\n Please restart execution.", string.Empty, 0);
                break;
            case 2:
                //MessageBox.Show("Warning: Only two files have been loaded into the directory C:\\Directory1\n Is this intended?.");
                Dts.Events.FireWarning(0, "File count", "Warning: Only two files have been loaded into the directory C:\\Directory1\n Is this intended?.", string.Empty, 0);
                Dts.TaskResult = (int)ScriptResults.Warning;
                break;
            default:
                Dts.TaskResult = (int)ScriptResults.Success;
                break;
        }

    }

    /// <summary>
    /// This enum provides a convenient shorthand within the scope of this class for setting the
    /// result of the script.
    /// 
    /// This code was generated automatically.
    /// </summary>
    enum ScriptResults
    {
        Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
        Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure,
        Warning = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Canceled,
    };

}
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
公共部分类ScriptMain:Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
/// 
///在控制流中执行此脚本任务时调用此方法。
///从该方法返回之前,请设置Dts.TaskResult的值以指示成功或失败。
///要打开“帮助”,请按F1。
/// 
公共图书馆
{
int numFiles=Convert.ToInt32(Dts.Variables[“numFiles”].Value.ToString());
开关(numFiles)
{
案例0:
//MessageBox.Show(“错误:目录C:\\Directory1\n请重新启动执行。”);
Dts.Events.firererror(0,“文件计数”,“错误:目录C:\\Directory1\n请重新启动执行。”,string.Empty,0);
打破
案例1:
//MessageBox.Show(“错误:在目录C:\\Directory1\n请重新启动执行中仅找到一个文件”);
Dts.Events.FireError(0,“文件计数”,“错误:在目录C:\\Directory1\n请重新启动执行”中只找到一个文件”,string.Empty,0);
打破
案例2:
//MessageBox.Show(“警告:只有两个文件已加载到目录C:\\Directory1\n这是预期的吗?);
Dts.Events.FireWarning(0,“文件计数”,“警告:只有两个文件已加载到目录C:\\Directory1\n这是预期的吗?”,string.Empty,0);
Dts.TaskResult=(int)ScriptResults.Warning;
打破
违约:
Dts.TaskResult=(int)ScriptResults.Success;
打破
}
}
/// 
///这个枚举在这个类的范围内提供了一个方便的速记来设置
///脚本的结果。
/// 
///此代码是自动生成的。
/// 
枚举脚本结果
{
Success=Microsoft.SqlServer.Dts.Runtime.dtsesecresult.Success,
Failure=Microsoft.SqlServer.Dts.Runtime.dtsesecresult.Failure,
警告=Microsoft.SqlServer.Dts.Runtime.dtsesecresult.cancelled,
};
}
似乎您希望有人在监视和响应程序包的运行。通常,这不是您希望SSI做的事情。它可以做这些事情,您可以有一个messagebox提示符来发现用户是否希望继续,但当它在服务器上运行时,该包将无法通过验证检查,因为它将发现它没有在交互模式下运行。这比DTS要好得多,因为人们会在服务器上留下消息框,并且由于没有人定期登录服务器,包会挂几个星期。如果需要同时为两个主机(有人值守和无人值守运行)提供服务,请使用System::InteractiveMode变量,以便在无人值守运行期间不尝试显示UI代码


在我看来,一个更好的选择是保持事件的触发如上所述,以便它在自动化环境中运行良好。然后,对于手动执行,为运行作业提供一个轻量级的.NET包装器。把文件检查也转移到这一点上。是的,工作会重复,但ETL和UI代码的分离会更清晰。

您希望如何打印消息<代码>MessageBox.Show将在visual studio中弹出,但在服务器上执行时会弹出。是的,这是我要做的事情之一。在服务器上运行此消息时,如何显示此消息?是否可以选择登录表?另一个选择是发送邮件。我只想停止某个包的运行。