用于自动化的SSIS C#脚本任务
我有一个SSIS包,它以一个脚本任务开始,以检查指定目录是否包含三个文件。如果有2个文件,它会打印警告;如果有1个或更少的文件,我会打印错误消息并终止程序。其思想是SQL代理将注册我的包并在指定的时间执行它。但是,我的脚本中必须满足以下条件:用于自动化的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
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中弹出,但在服务器上执行时会弹出。是的,这是我要做的事情之一。在服务器上运行此消息时,如何显示此消息?是否可以选择登录表?另一个选择是发送邮件。我只想停止某个包的运行。