我认为最好通过挂钩现有的Events来为您服务。使用您的代码作为基线,我将一个变量添加到一个包中,然后部署到 SQL Server 中。
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 将导致 Script 任务返回失败代码Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
,从而结束包执行。警告,如果您想停止包执行,那么您将修改脚本任务以指示它没有成功。我通过添加第三个 ScriptResult 枚举来做到这一点,该枚举被转换为DTSExecResult .Canceled (只有传达某些内容的其他选项没有按计划进行)。完整代码如下
[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,
};
}
似乎您希望有人在监视和响应包的运行。通常,这不是您希望 SSIS 做的事情。它可以做这些事情,你可以有一个消息框提示来发现用户是否希望继续,但是当它在服务器上运行时,包将无法通过验证检查,因为它会发现它没有在交互模式下运行。这比 DTS 好得多,因为人们会在服务器上留下消息框,并且由于没有人定期登录到服务器,包裹会挂起数周。如果您需要同时为两个主服务器(有人参与和无人参与的运行)提供服务,则使用 System::InteractiveMode 变量,这样您就不会尝试在无人参与的运行期间显示 UI 代码。
在我看来,一个更好的选择是保持 Event 的触发方式如上,以便它在自动化环境中运行良好。然后对于您的手动执行,提供一个轻量级的 .NET 包装器来运行作业。也将文件检查卸载到该位置。是的,工作是重复的,但您将更清晰地分离 ETL 和 UI 代码。