如何使用 ManagedDTS 从执行 SQL 任务映射结果集
How to map result sets from an execute SQL task using ManagedDTS
我正在尝试使用 C# (.Net 4.0) 和 ManagedDTS (10.0) 生成一些 SSIS (2008) 包。到目前为止,我已经设法生成了一个包并添加了一些连接和变量,现在我正在尝试填充控制流,我要添加的第一个任务是 "Execute SQL Task" 来检查源 table 有任何行,所以如果没有,我可以中止。如果我手动构建 SSIS 包,我将如何执行此操作是让执行 SQL 任务 运行 查询如下:
SELECT RecordExists = CASE WHEN EXISTS (SELECT * FROM [Schema].[TABLE] WHERE [COLUMN] IS NULL) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END
然后我将结果集 属性 设置为 "Single row",然后将结果映射到一个变量:
但是我看不到如何在 C# 中执行此操作,这是我目前所知道的:
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask;
...
public Package SsisPackage;
...
SsisPackage.Variables.Add("VAR_RecordExists", false, "User", false);
Executable RecordExists = SsisPackage.Executables.Add("STOCK:SQLTask");
TaskHost thRecordExists = RecordExists as TaskHost;
thRecordExists.Properties["Name"].SetValue(thRecordExists, "Do Records Exist?");
thRecordExists.Properties["SqlStatementSource"].SetValue(thRecordExists, "SELECT RecordExists = CASE WHEN EXISTS (SELECT * FROM [Schema].[TABLE] WHERE [COLUMN] IS NULL) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END");
thRecordExists.Properties["Connection"].SetValue(thRecordExists, "Stage");
thRecordExists.Properties["ResultSetType"].SetValue(thRecordExists, ResultSetType.ResultSetType_SingleRow);
我的第一个问题是最后一行错误:
当前上下文
中不存在名称 'ResultSetType'
我的第二个问题是,即使我能正常工作,我也不知道如何将结果集实际映射到变量,我一直在使用此处的文档,但它没有提及任何关于映射结果集的内容: https://docs.microsoft.com/en-us/sql/integration-services/building-packages-programmatically/adding-tasks-programmatically. I then found this: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.dts.tasks.executesqltask.executesqltask.resultsettype.aspx?f=255&MSPPError=-2147217396 它告诉我如何设置结果集类型但导致上述错误。它仍然没有提到如何设置结果集映射。
感谢任何帮助。
所以我没有找到使用 ManagedDTS 框架执行此操作的方法,但我确实让它工作了。
我最后做的是:
- 保存没有结果集映射的包。
- 使用 XmlDocument 打开包
我为此创建了一个助手 class,虽然它可能不是最高效或最干净的代码(我通常不是 C# 开发人员)但它似乎确实可以完成工作:
public class ResultSetBinding
{
string ResultName;
string DtsVariableName;
string TaskName;
public ResultSetBinding(string taskName, string resultName, string dtsVariableName)
{
TaskName = taskName;
ResultName = resultName;
DtsVariableName = dtsVariableName;
}
public void AddResultBinding(string filePath)
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlElement root = doc.DocumentElement;
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("DTS", "www.microsoft.com/SqlServer/Dts");
nsmgr.AddNamespace("SQLTask", "www.microsoft.com/sqlserver/dts/tasks/sqltask");
XmlNodeList executableNodes = root.SelectNodes("//DTS:Executable", nsmgr);
foreach (XmlNode executableNode in executableNodes)
{
if (IsExecuteSQLTask(executableNode, nsmgr))
{
if (IsSpecifiedTask(executableNode, nsmgr))
{
AddResultBindingToNode(doc, executableNode, nsmgr);
}
}
}
doc.PreserveWhitespace = true;
doc.Save(filePath);
}
private bool IsExecuteSQLTask(XmlNode executableNode, XmlNamespaceManager nsmgr)
{
foreach (XmlAttribute executableAttribute in executableNode.Attributes)
{
if (executableAttribute.Name == "DTS:ExecutableType")
{
return executableAttribute.Value.Contains("ExecuteSQLTask");
}
}
return false;
}
private bool IsSpecifiedTask(XmlNode executableNode, XmlNamespaceManager nsmgr)
{
foreach (XmlNode propertyNode in executableNode.ChildNodes)
{
if (propertyNode.Name == "DTS:Property")
{
foreach (XmlAttribute propertyAttribute in propertyNode.Attributes)
{
if (propertyAttribute.Name == "DTS:Name" && propertyAttribute.Value == "ObjectName" && propertyNode.InnerText == TaskName)
{
return true;
}
}
}
}
return false;
}
private void AddResultBindingToNode(XmlDocument doc, XmlNode executableNode, XmlNamespaceManager nsmgr)
{
foreach (XmlNode objectNode in executableNode.ChildNodes)
{
if (objectNode.Name == "DTS:ObjectData")
{
foreach (XmlNode sqlNode in objectNode.ChildNodes)
{
if (sqlNode.Name == "SQLTask:SqlTaskData")
{
XmlElement bindingElement = doc.CreateElement("SQLTask:ResultBinding", "www.microsoft.com/sqlserver/dts/tasks/sqltask");
bindingElement.SetAttribute("ResultName", "www.microsoft.com/sqlserver/dts/tasks/sqltask", ResultName);
bindingElement.SetAttribute("DtsVariableName", "www.microsoft.com/sqlserver/dts/tasks/sqltask", String.Format("User::{0}", DtsVariableName));
sqlNode.AppendChild(bindingElement);
}
}
}
}
}
}
然后我设置了以下 class 成员:
public List<ResultSetBinding> ResultBindings;
创建任务时添加结果绑定:
ResultSetBinding ResultBinding = new ResultSetBinding("Do Records Exist?", "RecordExists", "VAR_RecordExists");
ResultBindings.Add(ResultBinding);
然后一旦保存循环并添加结果绑定:
foreach (ResultSetBinding ResultBinding in ResultBindings)
{
ResultBinding.AddResultBinding(FilePath);
}
我正在尝试使用 C# (.Net 4.0) 和 ManagedDTS (10.0) 生成一些 SSIS (2008) 包。到目前为止,我已经设法生成了一个包并添加了一些连接和变量,现在我正在尝试填充控制流,我要添加的第一个任务是 "Execute SQL Task" 来检查源 table 有任何行,所以如果没有,我可以中止。如果我手动构建 SSIS 包,我将如何执行此操作是让执行 SQL 任务 运行 查询如下:
SELECT RecordExists = CASE WHEN EXISTS (SELECT * FROM [Schema].[TABLE] WHERE [COLUMN] IS NULL) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END
然后我将结果集 属性 设置为 "Single row",然后将结果映射到一个变量:
但是我看不到如何在 C# 中执行此操作,这是我目前所知道的:
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask;
...
public Package SsisPackage;
...
SsisPackage.Variables.Add("VAR_RecordExists", false, "User", false);
Executable RecordExists = SsisPackage.Executables.Add("STOCK:SQLTask");
TaskHost thRecordExists = RecordExists as TaskHost;
thRecordExists.Properties["Name"].SetValue(thRecordExists, "Do Records Exist?");
thRecordExists.Properties["SqlStatementSource"].SetValue(thRecordExists, "SELECT RecordExists = CASE WHEN EXISTS (SELECT * FROM [Schema].[TABLE] WHERE [COLUMN] IS NULL) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END");
thRecordExists.Properties["Connection"].SetValue(thRecordExists, "Stage");
thRecordExists.Properties["ResultSetType"].SetValue(thRecordExists, ResultSetType.ResultSetType_SingleRow);
我的第一个问题是最后一行错误: 当前上下文
中不存在名称 'ResultSetType'我的第二个问题是,即使我能正常工作,我也不知道如何将结果集实际映射到变量,我一直在使用此处的文档,但它没有提及任何关于映射结果集的内容: https://docs.microsoft.com/en-us/sql/integration-services/building-packages-programmatically/adding-tasks-programmatically. I then found this: https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.dts.tasks.executesqltask.executesqltask.resultsettype.aspx?f=255&MSPPError=-2147217396 它告诉我如何设置结果集类型但导致上述错误。它仍然没有提到如何设置结果集映射。
感谢任何帮助。
所以我没有找到使用 ManagedDTS 框架执行此操作的方法,但我确实让它工作了。
我最后做的是:
- 保存没有结果集映射的包。
- 使用 XmlDocument 打开包
我为此创建了一个助手 class,虽然它可能不是最高效或最干净的代码(我通常不是 C# 开发人员)但它似乎确实可以完成工作:
public class ResultSetBinding
{
string ResultName;
string DtsVariableName;
string TaskName;
public ResultSetBinding(string taskName, string resultName, string dtsVariableName)
{
TaskName = taskName;
ResultName = resultName;
DtsVariableName = dtsVariableName;
}
public void AddResultBinding(string filePath)
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlElement root = doc.DocumentElement;
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("DTS", "www.microsoft.com/SqlServer/Dts");
nsmgr.AddNamespace("SQLTask", "www.microsoft.com/sqlserver/dts/tasks/sqltask");
XmlNodeList executableNodes = root.SelectNodes("//DTS:Executable", nsmgr);
foreach (XmlNode executableNode in executableNodes)
{
if (IsExecuteSQLTask(executableNode, nsmgr))
{
if (IsSpecifiedTask(executableNode, nsmgr))
{
AddResultBindingToNode(doc, executableNode, nsmgr);
}
}
}
doc.PreserveWhitespace = true;
doc.Save(filePath);
}
private bool IsExecuteSQLTask(XmlNode executableNode, XmlNamespaceManager nsmgr)
{
foreach (XmlAttribute executableAttribute in executableNode.Attributes)
{
if (executableAttribute.Name == "DTS:ExecutableType")
{
return executableAttribute.Value.Contains("ExecuteSQLTask");
}
}
return false;
}
private bool IsSpecifiedTask(XmlNode executableNode, XmlNamespaceManager nsmgr)
{
foreach (XmlNode propertyNode in executableNode.ChildNodes)
{
if (propertyNode.Name == "DTS:Property")
{
foreach (XmlAttribute propertyAttribute in propertyNode.Attributes)
{
if (propertyAttribute.Name == "DTS:Name" && propertyAttribute.Value == "ObjectName" && propertyNode.InnerText == TaskName)
{
return true;
}
}
}
}
return false;
}
private void AddResultBindingToNode(XmlDocument doc, XmlNode executableNode, XmlNamespaceManager nsmgr)
{
foreach (XmlNode objectNode in executableNode.ChildNodes)
{
if (objectNode.Name == "DTS:ObjectData")
{
foreach (XmlNode sqlNode in objectNode.ChildNodes)
{
if (sqlNode.Name == "SQLTask:SqlTaskData")
{
XmlElement bindingElement = doc.CreateElement("SQLTask:ResultBinding", "www.microsoft.com/sqlserver/dts/tasks/sqltask");
bindingElement.SetAttribute("ResultName", "www.microsoft.com/sqlserver/dts/tasks/sqltask", ResultName);
bindingElement.SetAttribute("DtsVariableName", "www.microsoft.com/sqlserver/dts/tasks/sqltask", String.Format("User::{0}", DtsVariableName));
sqlNode.AppendChild(bindingElement);
}
}
}
}
}
}
然后我设置了以下 class 成员:
public List<ResultSetBinding> ResultBindings;
创建任务时添加结果绑定:
ResultSetBinding ResultBinding = new ResultSetBinding("Do Records Exist?", "RecordExists", "VAR_RecordExists");
ResultBindings.Add(ResultBinding);
然后一旦保存循环并添加结果绑定:
foreach (ResultSetBinding ResultBinding in ResultBindings)
{
ResultBinding.AddResultBinding(FilePath);
}