如何使用 ManagedDTS 映射执行 SQL 任务的结果集

问题描述 投票:0回答:2

我正在尝试使用 C# (.Net 4.0) 和 ManagedDTS (10.0) 生成一些 SSIS (2008) 包。到目前为止,我已经成功生成了一个包并添加了一些连接和变量,现在我正在尝试填充控制流,我尝试添加的第一个任务是“执行 SQL 任务”来检查源表是否有任何行,所以如果没有,我可以中止。如果我手动构建 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

然后,我将 ResultSet 属性设置为“单行”,然后将结果映射到变量:

但是我不知道如何在 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: //learn.microsoft.com/en-us/sql/integration-services/building-packages-programmatically/adding-tasks-programmatically。然后我发现了这个:https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.dts.tasks.executesqltask.executesqltask.resultsettype.aspx?f=255&MSPPError=-2147217396它告诉我如何设置结果集类型但会导致上述错误。还是没有提到如何设置结果集映射。

如有任何帮助,我们将不胜感激。

c# ssis ssis-2008
2个回答
0
投票

所以我没有找到使用 ManagedDTS 框架来做到这一点的方法,但我确实让它工作了。

我最终做的是:

  • 保存没有结果集映射的包。
  • 使用 XmlDocument 打开包

我为此创建了一个辅助类,虽然它可能不是最有效或最干净的代码(我通常不是 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);
                        }
                    }
                }
            }
        }
    }

然后我设置以下班级成员:

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);
}

0
投票

这是一个老问题,但我添加了一个答案,因为它在我的搜索中名列前茅。操作 XML 的想法没有吸引力,所以我继续寻找并最终找到了一种方法。

设置 ResultSetType 时,我刚刚传递了一个包含“允许值”的字符串,并且工作正常。 executeSQLTask.Properties["ResultSetType"].SetValue(executeSQLTask, "ResultSetType_SingleRow");

要获取结果,您需要结果绑定:

ExecuteSQLTask task = executeSQLTask.InnerObject as ExecuteSQLTask; task.ResultSetBindings.Add(); IDTSResultBinding resultBinding = task.ResultSetBindings.GetBinding(0); resultBinding.ResultName = "0"; resultBinding.DtsVariableName = "User::my_object_variable";

这成功生成了一个 SQL 任务,将查询结果集加载到对象变量中以供下游使用。

© www.soinside.com 2019 - 2024. All rights reserved.