Hi all,
I've inherited a package that uses a script transform source in a data flow to parse a complex text file.
I've noticed that any error in the data flow is caught by the source (ie pkey violations in the oledb destination) and I get a script component:runtime error Script component has encountered an exception in user code:
the script is:
/* Microsoft SQL Server Integration Services Script Component * Write scripts using Microsoft Visual C# 2008. * ScriptMain is the entry point class of the script.*/ using System; using System.Data; using Microsoft.SqlServer.Dts.Pipeline.Wrapper; using Microsoft.SqlServer.Dts.Runtime.Wrapper; using System.Collections.Generic; using System.Reflection; using System.Linq; /// <summary> /// Provides a data source based on a GRID file. /// </summary> [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute] public class ScriptMain : UserComponent { #region Properties /// <summary> /// Gets the path to the file to be used as a data source. /// </summary> private string SourceFilePath { get { return Variables.CurrentLocalDownloadFilePathExtracted; } } #endregion #region Methods /// <summary> /// Creates rows and adds them to the output buffer(s). /// </summary> public override void CreateNewOutputRows() { const string VALID_DATA_CHARS = " .1234567890"; try { int ncols = 0; int nrows = 0; decimal xllcorner = 0.0M; decimal xllcenter = 0.0M; decimal yllcorner = 0.0M; decimal yllcenter = 0.0M; decimal cellsize = 0.0M; decimal nodata = 0.0M; decimal longitude = 0.0M; decimal latitude = 0.0M; string line; int counter = 0; // Read the file and process it line by line. using (System.IO.StreamReader file = new System.IO.StreamReader(this.SourceFilePath)) { while ((line = file.ReadLine()) != null) { counter++; switch (counter) { // First 6 rows are "header" info, then the rest contains the "real data". case 1: if (line.ToLower().StartsWith("ncols")) { ncols = Int32.Parse(line.Substring(5)); } else { throw new System.IO.InvalidDataException("File Error: " + this.SourceFilePath + ", row: " + counter.ToString() + "\nData in error:\n" + line); } break; case 2: if (line.ToLower().StartsWith("nrows")) { nrows = Int32.Parse(line.Substring(5)); } else { throw new System.IO.InvalidDataException("File Error: " + this.SourceFilePath + ", row: " + counter.ToString() + "\nData in error:\n" + line); } break; case 3: if (line.ToLower().StartsWith("xll")) { if (line.ToLower().StartsWith("xllcorner")) { xllcorner = Decimal.Parse(line.Substring(9)); } else { xllcenter = Decimal.Parse(line.Substring(9)); } } else { throw new System.IO.InvalidDataException("File Error: " + this.SourceFilePath + ", row: " + counter.ToString() + "\nData in error:\n" + line); } break; case 4: if (line.ToLower().StartsWith("yll")) { if (line.ToLower().StartsWith("yllcorner")) { yllcorner = Decimal.Parse(line.Substring(9)); } else { yllcenter = Decimal.Parse(line.Substring(9)); } } else { throw new System.IO.InvalidDataException("File Error: " + this.SourceFilePath + ", row: " + counter.ToString() + "\nData in error:\n" + line); } break; case 5: if (line.ToLower().StartsWith("cellsize")) { cellsize = Decimal.Parse(line.Substring(8)); // now we have all the header info we need - work out our starting latitude and longitude if (xllcenter == 0.0M && xllcorner > 0.0M) { xllcenter = xllcorner + (cellsize / 2.0M); yllcenter = yllcorner + (cellsize / 2.0M); } longitude = xllcenter; latitude = yllcenter + ((nrows - 1) * cellsize); } else { throw new System.IO.InvalidDataException("File Error: " + this.SourceFilePath + ", row: " + counter.ToString() + "\nData in error:\n" + line); } break; case 6: if (line.ToLower().StartsWith("nodata")) { nodata = Decimal.Parse(line.Substring(12)); } else { throw new System.IO.InvalidDataException("File Error: " + this.SourceFilePath + ", row: " + counter.ToString() + "\nData in error:\n" + line); } break; default: if (counter <= (nrows + 6) && VALID_DATA_CHARS.Contains(line[0].ToString())) { this.ProcessLine(line.Trim(), longitude, latitude, cellsize); latitude = latitude - cellsize; } else if (counter <= (nrows + 6)) { throw new System.IO.InvalidDataException("File Error: " + this.SourceFilePath + ", row: " + counter.ToString() + "\nData in error:\n" + line); } break; } } } } catch { throw; } } /// <summary> /// Processes an individual line of .grid file data /// </summary> /// <param name="line">Line of data values</param> /// <param name="longitude">Starting longitude for the line of data</param> /// <param name="latitude">Starting latitude for the line of data</param> /// <param name="cellSize">The longitude "step size" for each column in the data</param> private void ProcessLine(string line, decimal longitude, decimal latitude, decimal cellSize) { string[] dataValues = line.Split(new char[] { ' ' }); foreach (string dataValue in dataValues) { decimal actualValue = 0.0M; try { actualValue = Decimal.Parse(dataValue, System.Globalization.NumberStyles.Any); } catch (System.OverflowException ex) { // ignore - the overflows are "too small", not "too big" - writes a zero to the database. } actualValue = decimal.Round(actualValue, 3); this.AddRowToOutputBuffer(longitude, latitude, actualValue); longitude += cellSize; } } /// <summary> /// Adds a new row to the SSIS output buffer based on the data provided. /// </summary> /// <param name="longitude"></param> /// <param name="latitude"></param> /// <param name="actualValue"></param> private void AddRowToOutputBuffer(decimal longitude, decimal latitude, decimal actualValue) { GridFileOutputBuffer.AddRow(); GridFileOutputBuffer.Longitude = longitude; GridFileOutputBuffer.Latitude = latitude; GridFileOutputBuffer.ActualValue = actualValue; } #region Unused public override void PreExecute() { base.PreExecute(); /* Add your code here for preprocessing or remove if not needed */ } public override void PostExecute() { base.PostExecute(); /* Add your code here for postprocessing or remove if not needed You can set read/write variables here, for example: Variables.MyIntVar = 100 */ } #endregion #endregion }
Is there a quick fix or will I need to rewrite it to use Me.ComponentMetaData.FireError?
Adelaide, Australia