【问题标题】:Using SSIS Script task to read XML from variable object LoadXml fails使用 SSIS 脚本任务从变量对象 LoadXml 读取 XML 失败
【发布时间】:2016-12-03 08:19:13
【问题描述】:

我有一个构建 XML 格式数据的 SQL 语句 (SQL server 2014)。我将其拉入 SSIS (2013) 对象变量。如果我将 SQL 放入数据流任务中以进入文本文件,它就可以工作。但是,没有编码头。由于返回数据的大小,不能转换为 NVARCHAR - 数据会被截断。

所以,我有一个 sql 任务,相同的查询: 结果集 = XML;变量数据类型 = 对象(如果我尝试字符串,它会失败)

所以,在这里待了很长时间后,我发现了各种可以使用 XmlWriter 和 XmlWriterSettings 的好东西。厉害,厉害但是——我似乎无法让脚本任务(C#)正确读取(或格式化/定义)XML 对象。我不断收到“DTS 脚本任务在用户代码中遇到异常”

我在 LoadXML 语句处设置了一个断点 - 验证了该变量确实具有 XML 数据 - 有趣的是,它被...包围了。在调试模式下,具体错误是“根级别的数据无效。第 1 行,位置 1。”

它在 LoadXML 语句中引发异常——我错过了什么?我需要定义 XML 布局(字段)吗?注释掉的测试字符串没有问题。没有失败。标题写了。

有什么想法吗?

更新:它也因我的测试数据的字符串版本而失败,没有根标记。

public void Main()
        {

            Variables varCollection = null;
            Dts.VariableDispenser.LockForWrite("User::PCC_XML");
            Dts.VariableDispenser.GetVariables(ref varCollection);

            XmlDocument xdoc = new XmlDocument();

            XmlWriterSettings settings = new XmlWriterSettings
            {
                Encoding = Encoding.UTF8,
                ConformanceLevel = ConformanceLevel.Document,
                OmitXmlDeclaration = false,
                CloseOutput = true,
                Indent = true,
                IndentChars = "  ",
                NewLineHandling = NewLineHandling.Replace
            };    

            xdoc.LoadXml(varCollection["User::PCC_XML"].Value.ToString());

            //xdoc.LoadXml("<xml><foo></foo></xml>");

            using ( StreamWriter sw = File.CreateText("C:\\test_xml.xml") )
            using ( XmlWriter writer = XmlWriter.Create(sw, settings))
            {
                xdoc.WriteContentTo(writer);
                writer.Close();
            }    

            Dts.TaskResult = (int)ScriptResults.Success;
        }

我的 XML 的精简版是(包括添加的 ROOT)

<ROOT>
    <Universal_letters>
        <Universal_letter>
            <docID>123456</docID>
            <Letter_Code>123</Letter_Code>
            <Callback_Phone>1-888-111-111</Callback_Phone>
            <Delivery_Methods>
                <Delivery_Method />
                <Print_Queue />
            </Delivery_Methods>
            <Requested_Date>2016-07-28</Requested_Date>
            <Consumer_First_Name>Bubba</Consumer_First_Name>
            <Consumer_Last_Name>Bubbster</Consumer_Last_Name>
            <Consumer_Address_1>123 Street Way</Consumer_Address_1>
        </Universal_letter>
    </Universal_letters>
</ROOT>

【问题讨论】:

  • 对不起,我对 xml 不太熟悉,所以我通过 SQL 来解决这个问题。下面是一些 TSQL,它将数据分解为 4000 个字符的输出。利用此逻辑,您可以在 ssis 包的控制流中循环执行此操作,或在 c# 中执行类似操作。抱歉,作为评论,这不是很可读。声明 @v varchar(max) = '' 声明 @c int; set @count = len(@v)/4000 if (len(@v)%4000 > 0) set @c = @c + 1 declare @i int = @c while (@count > 0) begin select substring(@ v,0+(4000*(@i-@c)),4000+(4000*(@i-@c))) 设置@c = @c - 1 结束

标签: c# sql-server xml ssis script-task


【解决方案1】:

您是否尝试过删除 XML 元素之间的间距或检查任何特殊字符。您的 XML 很好,脚本任务中的 C# 代码也可以正常工作。 我重新创建了与您的查询中提到的相同的场景。 因此,我认为问题确实出在运行时生成并设置为PCC_XML 变量的输入的实际XML 上。将其写入变量的方式可能有些可疑。一些空格或特殊字符可能会导致同样的情况发生。 如果对您有帮助,请将其标记为已回答。

【讨论】:

    【解决方案2】:

    我无法让我的 XML 样本按照 Mohd 的建议工作。然而,今天,我发现了这个http://www.sql-server-performance.com/2013/export-to-xml-using-ssis/(它使用了一个字符串作为结果集,以及一个用于转换和导出 XML 的脚本任务。)结合 https://stackoverflow.com/a/14840090/4509043 - 用于编码。把我带到我需要去的地方。

    有趣的是,c# 脚本任务并没有截断我的任何大型 XML 数据 - 与 NVARCHAR(MAX) 不同。所以这太棒了!还值得一提的是,OLE DB 连接不起作用,它必须是 ADO.NET。

    最终解决方案: User::PCC_XML 是字符串数据类型。 SQL 任务具有单行结果 - XML 类型。

    我的最终工作 C# 代码是:

    在命名空间声明之前 - 与其他命名空间一起

    using System.Xml; //added - for xml
    using System.Text; //added - for Encoding
    using System.IO; // added - for file writing
    

    主进程

    public void Main()
            {
    
                XmlDocument xdoc = new XmlDocument();
    
                // will ensure that XML exported will have opening tag
                // <?xml version="1.0" encoding="UTF-8"?>
                XmlWriterSettings settings = new XmlWriterSettings
                {
                    Encoding = Encoding.UTF8,
                    ConformanceLevel = ConformanceLevel.Document,
                    OmitXmlDeclaration = false,
                    CloseOutput = true,
                    Indent = true,
                    IndentChars = "  ",
                    NewLineHandling = NewLineHandling.Replace
                };
    
                // strip out the <root> </root> tags on insert into string
                string strXML = Dts.Variables["User::PCC_XML"].Value.ToString().Replace("<ROOT>", "").Replace("</ROOT>", "");
    
                xdoc.LoadXml(strXML.ToString());
    
                // test destination
                using ( StreamWriter sw = File.CreateText("C:\\test_xml.xml") )
                using ( XmlWriter writer = XmlWriter.Create(sw, settings))
                {
                    xdoc.WriteContentTo(writer);
                    writer.Close();
                }
    
                Dts.TaskResult = (int)ScriptResults.Success;
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多