1

I am getting the below error when trying to generate a package through BIML using a ScriptTask as a datasource. I have a large (circa 5GB) XML file to load and wanted to use a StreamReader to get the data into the database.

'Output0Buffer' does not contain a definition for 'PORTF_LIST' and no extension method 'PORTF_LIST' accepting a first argument of type 'Output0Buffer' could be found (are you missing a using directive or an assembly reference?).

This is occurring for each column. The columns are dynamic and come from a separate method in a c# class looking at the dacpac so should be the same names and casing everywhere.

Sample of the file as below:

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

Output buffer is defined as below (there are 250 odd columns, but all follow the same pattern:

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

The script task code where I am trying to add to the buffer is below:

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

I've checked the code in a console app and it reads the XML file fine, but no luck with the BIML. There are about 250 odd columns so I am trying to avoid doing this manually so if you have any ideas what I am doing wrong I'd really appreciate it!

3
  • Quick glance through it, things look approximate. What I'm held up on is where the reference to ColumnName is coming from. I'll try to carve out some time after work to get a working repro up. Any chance you can pop a sample of sourceFile's contents into the question? Commented Dec 5, 2017 at 19:05
  • Sorry Bill, my bad. I've corrected the question now I had removed all the columns for brevity just using ColumnName as an example. That error occurs once for every column that I assign to the buffer column below: Output0Buffer.PORTF_LIST = myXmlData.PORTF_LIST; Output0Buffer.PRT_FULL_NAME = myXmlData.PRT_FULL_NAME; Output0Buffer.ISIN = myXmlData.ISIN; I will try to get a cut down version of the file. Commented Dec 6, 2017 at 8:58
  • I am currently facing a similar problem: I read the table definition from a DB and I want to create a Output-Column per column in the table. In my biml script within my "<columns></columns>" I loop over my column collection (foreach DataRow col in...), but I receive some error like "text is not allowed in columns...". How did you construct your <#=BufferColumns#>? Commented Dec 21, 2017 at 15:37

1 Answer 1

1

It seems that the script task does not like underscores in the OutputBuffer.

I created a stub package manually and intellisense had PORTFLIST rather than PORTF_LIST when assigning the value.

So that snippit of code should be:

Output0Buffer.AddRow();
Output0Buffer.PORTFLIST = myXmlData.PORTF_LIST;
Output0Buffer.PRTFULLNAME = myXmlData.PRT_FULL_NAME;
Output0Buffer.ISIN = myXmlData.ISIN

I have another error, my favorite "EmitSsis. Internal Compiler Error: Workflow EmitSsis contains fatal errors.", but at least this one is solved!

Thanks Bill for your help, and sorry I led you down the garden path with the wrong column name in the posted error, or you probably would have known the issue!

Sign up to request clarification or add additional context in comments.

1 Comment

No worries, you've enriched universe for the next generation of people running into the error. ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.