BIML SSIS ScriptTask作为数据源-OutputBuffer出错

BIML SSIS ScriptTask作为数据源-OutputBuffer出错,ssis,biml,Ssis,Biml,在尝试使用ScriptTask作为数据源通过BIML生成包时,我遇到以下错误。我有一个大的(大约5GB)XML文件要加载,希望使用StreamReader将数据导入数据库 “Output0Buffer”不包含“PORTF_LIST”的定义,并且找不到接受“Output0Buffer”类型的第一个参数的扩展方法“PORTF_LIST”(是否缺少using指令或程序集引用?) 每个列都会发生这种情况。这些列是动态的,来自一个c#类中查看dacpac的单独方法,因此所有列的名称和大小写都应该相同 文件

在尝试使用ScriptTask作为数据源通过BIML生成包时,我遇到以下错误。我有一个大的(大约5GB)XML文件要加载,希望使用StreamReader将数据导入数据库

“Output0Buffer”不包含“PORTF_LIST”的定义,并且找不到接受“Output0Buffer”类型的第一个参数的扩展方法“PORTF_LIST”(是否缺少using指令或程序集引用?)

每个列都会发生这种情况。这些列是动态的,来自一个c#类中查看dacpac的单独方法,因此所有列的名称和大小写都应该相同

文件样本如下:

<ANALYTICS>
  <INSTRUMENTS ASOF_DATE="3/31/2017" CREATE_DATE="4/2/2017" RECORDS="3763">
    <INSTRUMENT>
      <PORTF_LIST>XX1245897</PORTF_LIST>
      <PRT_FULL_NAME>Convertible Bonds</PRT_FULL_NAME>
      <ISIN>11803384</ISIN>
    </INSTRUMENT>
     </INSTRUMENTS>
</ANALYTICS>

XX1245897
可转换债券
11803384
输出缓冲区的定义如下(有250多列,但都遵循相同的模式:

           <OutputBuffers>
                <OutputBuffer Name="Output0" IsSynchronous="false">
                    <Columns>
<Column Name="PORTF_LIST" DataType="String" Length="255"/>
<Column Name="PRT_FULL_NAME" DataType="String" Length="255"/>
<Column Name="ISIN" DataType="String" Length="255"/>
                    </Columns>                    
                </OutputBuffer>                                 
            </OutputBuffers>   

我试图添加到缓冲区的脚本任务代码如下:

    <#@ property name="Elements" type="String" #>  
    <#@ property name="Columns" type="String" #>  
    <#@ property name="BufferColumns" type="String" #>  
    <#@ property name="RootElement" type="String" #>  
    <ScriptComponentProject ProjectCoreName="SC_eb1debcd2374468ebccbbfad4fbe5976" Name="XmlSource">
              <AssemblyReferences>
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSPipelineWrap" />
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSRuntimeWrap" />
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.PipelineHost" />
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.TxScript" />                  
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.ManagedDTS.dll" />
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.ScriptTask.dll" />
                <AssemblyReference AssemblyPath="System.dll" />
                <AssemblyReference AssemblyPath="System.AddIn.dll" />
                <AssemblyReference AssemblyPath="System.Data.dll" />
                <AssemblyReference AssemblyPath="System.Windows.Forms.dll" />
                <AssemblyReference AssemblyPath="System.Xml.dll" />
                <AssemblyReference AssemblyPath="System.Xml.Linq.dll" />
                <AssemblyReference AssemblyPath="System.Core.dll" />
             </AssemblyReferences>
            <OutputBuffers>
                <!--    
                Define what your buffer is called and what it looks like
                Must set IsSynchronous as false. Otherwise it is a transformation
                (one row enters, one row leaves) and not a source.
                -->
                <OutputBuffer Name="Output0" IsSynchronous="false">
                    <Columns>
                        <#=BufferColumns#>
                    </Columns>                    
                </OutputBuffer>                                 
            </OutputBuffers>              
              <Files>
                <File Path="Properties\AssemblyInfo.cs">
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyTitle("XmlSource")]
[assembly: AssemblyDescription("Script Component as source")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("XmlSource")]
[assembly: AssemblyCopyright("Copyright @ 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.0.*")]
</File>
<File Path="main.cs">
<![CDATA[

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Security;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Forms;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{

        public override void PreExecute()
        {
            base.PreExecute();

        }

        public override void PostExecute()
        {
            base.PostExecute();
        }

        public string sourceFile =  Dts.Variables["User::FileName"].Value.ToString();

        public override void CreateNewOutputRows()
        {
            foreach (var myXmlData in (
                   from elements in StreamReader(sourceFile, "INSTRUMENT")
                   select new 
                        {
PORTF_LIST = elements.Element("PORTF_LIST").Value,
PRT_FULL_NAME = elements.Element("PRT_FULL_NAME").Value,
ISIN = elements.Element("ISIN").Value

                        }
                ))
                {
                    try
                    {
                        Output0Buffer.AddRow();
    Output0Buffer.PORTF_LIST = myXmlData.PORTF_LIST;
    Output0Buffer.PRT_FULL_NAME = myXmlData.PRT_FULL_NAME;
    Output0Buffer.ISIN = myXmlData.ISIN;
                    }
                    catch (Exception e)
                    {
                        string errorMessage = string.Format("Data retrieval failed: {0}", e.Message);
                        bool cancel;
                        ComponentMetaData.FireError(0, ComponentMetaData.Name, errorMessage,string.Empty,0, out cancel);
                    }

                }


        }


        public static IEnumerable<XElement> StreamReader(String filename, string elementName)
        {

                         // Create an XML reader for this file.
                        using (XmlReader reader = XmlReader.Create(filename))
                        {
                            reader.MoveToContent(); // will not advance reader if already on a content node; if successful, ReadState is Interactive
                            reader.Read();          // this is needed, even with MoveToContent and ReadState.Interactive
                            while(!reader.EOF && reader.ReadState == ReadState.Interactive)
                            {
                                if(reader.NodeType == XmlNodeType.Element && reader.Name.Equals(elementName))
                                {
                                     // this advances the reader...so it's either XNode.ReadFrom() or reader.Read(), but not both
                                     var matchedElement = XNode.ReadFrom(reader) as XElement;
                                     if(matchedElement != null)
                                         yield return matchedElement;
                                }
                                else
                                    reader.Read();
                            }
                            reader.Close();

                        }
        }

}
]]>
                </File>
              </Files>
              <ReadOnlyVariables>
                  <Variable Namespace="User" DataType="String" VariableName="FileName" />
              </ReadOnlyVariables>
              <ReadWriteVariables>
              </ReadWriteVariables>
            </ScriptComponentProject>

运用系统反思;
使用System.Runtime.CompilerServices;
[汇编:AssemblyTitle(“XmlSource”)]
[程序集:AssemblyDescription(“脚本组件作为源”)]
[程序集:程序集配置(“”)]
[大会:大会公司(“)]
[汇编:AssemblyProduct(“XmlSource”)]
[大会:大会版权所有(“版权@2017”)]
[组装:组装商标(“”)]
[大会:大会文化(“”)
[汇编:汇编版本(“1.0.*)]
StreamReader(字符串文件名、字符串元素名)
{
//为此文件创建XML读取器。
使用(XmlReader=XmlReader.Create(文件名))
{
reader.MoveToContent();//如果已经在内容节点上,则不会提升reader;如果成功,则ReadState是交互式的
reader.Read();//即使使用MoveToContent和ReadState.Interactive,这也是必需的
而(!reader.EOF&&reader.ReadState==ReadState.Interactive)
{
if(reader.NodeType==XmlNodeType.Element&&reader.Name.Equals(elementName))
{
//这将提高读卡器的性能…因此它是XNode.ReadFrom()或reader.Read(),但不是两者都是
var matchedElement=XNode.ReadFrom(reader)作为XElement;
如果(匹配元素!=null)
收益率匹配元素;
}
其他的
reader.Read();
}
reader.Close();
}
}
}
]]>

我在一个控制台应用程序中检查了代码,它可以很好地读取XML文件,但BIML没有成功。大约有250多列,因此我试图避免手动执行此操作,因此如果您知道我做错了什么,我将非常感谢!

脚本任务似乎不喜欢OutputBuffer中的下划线

我手动创建了一个存根包,intellisense在赋值时使用了PORTFLIST而不是PORTF_列表

因此,代码片段应该是:

Output0Buffer.AddRow();
Output0Buffer.PORTFLIST = myXmlData.PORTF_LIST;
Output0Buffer.PRTFULLNAME = myXmlData.PRT_FULL_NAME;
Output0Buffer.ISIN = myXmlData.ISIN
我还有另一个错误,我最喜欢的“EmitSsis.internalcompiler error:Workflow EmitSsis包含致命错误”,但至少解决了这个错误


感谢比尔的帮助,很抱歉,我在发布的错误中用错误的列名引导你走上花园小径,否则你可能已经知道了问题所在!

快速浏览一下,事情看起来很接近。我遇到的问题是列名的来源。我会在下班后抽出一些时间来找工作重新编程。你有没有可能在问题中弹出一个
sourceFile
的内容示例?对不起,比尔,我的错。我已经更正了这个问题。为了简洁起见,我仅以ColumnName为例删除了所有列。对于我分配给下面缓冲区列的每一列,该错误都会发生一次:Output0Buffer.PORTF\u LIST=myXmlData.PORTF_LIST;Output0Buffer.PRT_FULL_NAME=myXmlData.PRT_FULL_NAME;Output0Buffer.ISIN=myXmlData.ISIN;我将尝试获取该文件的精简版本。我当前面临类似的问题:我从数据库读取表定义,并希望在表中的每列创建一个输出列。在我的我循环我的列集合(foreach DataRow col in…),但我收到一些错误,如“列中不允许使用文本…”。您是如何构建的?不用担心,您已经为下一代遇到错误的人丰富了宇宙的内容。;)