2017-12-05 8 views
1

ScriptTaskをデータソースとして使用してBIMLを使用してパッケージを生成しようとすると、以下のエラーが発生します。私は大きな(5GBの)XMLファイルを読み込み、StreamReaderを使ってデータベースにデータを取得したかったのです。データソースとしてのBIML SSIS ScriptTask - OutputBufferでのエラー

'Output0Buffer'に 'PORTF_LIST'の定義が含まれておらず、 'Output0Buffer'タイプの最初の引数を受け入れる拡張メソッド 'PORTF_LIST'が見つかりませんでした(usingディレクティブまたはアセンブリ参照がありませんか?

これは各列に発生しています。列は動的であり、dacpacを見ているC#クラスの別のメソッドから来ていますので、どこにでも同じ名前で囲む必要があります。以下のようにファイルの

サンプル:

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

出力バッファが以下のように定義される(が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 retreval 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> 

私はコンソールでコードをチェックしましたappとそれはXMLファイルを正常に読み取りますが、BIMLと運がない。約250の奇数の列がありますので、私は手動でこれを行うことを避けようとしていますので、私が間違っているアイデアがあれば、本当に感謝します!

+0

それをすばやく見て、物事はおおよそ見えます。私はColumnNameへの参照がどこから来ているのかを把握しています。私は仕事の後に仕事をしていくために時間を刻むつもりです。 'sourceFile'の内容のサンプルを質問にポップできますか? – billinkc

+0

申し訳ありませんビル、悪いです。私は問題を修正したので、例としてColumnNameを使用するだけで簡潔さのためにすべての列を削除しました。そのエラーは、私が下のバッファ列に割り当てた列ごとに1回発生します。 Output0Buffer.PORTF_LIST = myXmlData.PORTF_LIST;Output0Buffer.PRT_FULL_NAME = myXmlData.PRT_FULL_NAME; Output0Buffer.ISIN = myXmlData.ISIN; ファイルの縮小版を取得しようとします。 – guytz72

+0

私は現在、同様の問題に直面しています。私はDBからテーブル定義を読み込み、テーブルに列ごとにOutput-Columnを作成したいと思います。私の ""内のbimlスクリプトでは、私の列コレクション(foreach DataRow col in ...)をループしますが、 "text is not columns ..."のようなエラーが表示されます。 <#= BufferColumns#>はどのように構築しましたか? – Tyron78

答えて

1

スクリプトタスクはOutputBufferのアンダースコアが気に入らないようです。

スタブパッケージを手動で作成しましたが、intellisenseは値を割り当てるときにPORTF_LISTではなくPORTFLISTを持っていました。しかし、少なくとも、この一つが解決される「ワークフローEmitSsis致命的なエラーが含まれています。EmitSsis内部コンパイラエラー。」

私は別のエラーを持っている
Output0Buffer.AddRow(); 
Output0Buffer.PORTFLIST = myXmlData.PORTF_LIST; 
Output0Buffer.PRTFULLNAME = myXmlData.PRT_FULL_NAME; 
Output0Buffer.ISIN = myXmlData.ISIN 

は、私のお気に入りは:

だからコードのそのsnippitはする必要があります!

ご協力ありがとうございました。申し訳ありませんが、間違った列名で庭の道を案内してくれました。

+0

次の世代の人々がこのエラーに遭遇した場合、あなたは宇宙を豊かにしました。 ;) – billinkc

関連する問題