2016-07-28 54 views
0

我有一个SQL语句(SQL Server 2014),它构建出XML格式的数据。我正在将此引入SSIS(2013)对象变量。如果我将SQL放入数据流任务以进入文本文件,则可以使用。但是,没有编码头。由于返回数据的大小,转换为NVARCHAR不是一种选择 - 数据会被截断。使用SSIS脚本任务从变量对象读取XML LoadXml失败

所以,相反,我有一个SQL任务,相同的查询: ResultSet = 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的skinnied下降版本(包括得到补充说,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> 
+0

对不起,我不是太熟悉XML,所以我走近这虽然SQL。下面是一些将把数据分解成4000个字符输出的TSQL。利用这个逻辑,你可以在ssis包的控制流程的一个循环中做这件事,或者在c#中做类似的事情。 \t 对不起,这不是一个可读的评论。 \t declare @v varchar(max)='' declare @c int; (@count> 0) set @count = len(@v)/ 4000 if(len(@v)%4000> 0)set @c = @c + 1 declare @i int = @c while(@count> 0) 开始 选择子字符串(@ v,0 +(4000 *(@ i- @ c)),4000+(4000 *(@ i- @ c))) set @c = @c - 1 end –

回答

0

你有没有尝试删除XML元素之间的间隔或检查任何特殊字符。你的XML很好,脚本任务中的C#代码也在做它的工作。 我重新创建了与查询中提到的相同的场景。 所以,我认为这个问题确实与运行时生成的实际XML有关,并且设置为PCC_XML变量的输入。可能有些东西可能会被写入变量中。一些间距或特殊字符可能会导致相同的情况发生。 如果它对您有帮助,请将其标为已回答。

0

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

有趣的是,与NVARCHAR(MAX)不同,c#脚本任务并未截断我的任何大XML数据。太棒了!还值得一提的是,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 

主要PROC

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