Search code examples
c#sqldb2ibm-midrange

Index was outside the bounds of the array in MSCORLIB.DLL


I will be amazed if I find a solution for this, since it is very specific and vague, but I figured I would try. I'll try to give as much information as humanly possible, since I've been searching for answers for some time now.

I am building a utility in C# which copies records from a file in a library on the i-series/AS400 and builds an encrypted text file with each record from the AS400 as a comma separated string. In the file, it will have values like filename, fieldvalue1, fieldvalue2, fieldvalue3. I then take that text file to another PC, and run a C# utility which copies that record into the same file name in a library over there on a different i-series machine. Unfortunately, I receive the outside bounds of the array exception in some cases, but I cannot determine why. In the record just prior to the exception, the record looks pretty much the same and it works fine. My code is below in a nutshell. I usually don't give up, but I don't expect to ever figure this out. If someone does, I'll probably sing karaoke tonight.

// Select records from AS400 file and write them to text file
Recordset rs = new Recordset();
sqlQuery = "SELECT * FROM " + dataLibrary + "." + fileName;

try
{
    rs.Open(sqlQuery, con);

    while (!rs.EOF)
    {
        int[] fieldLengths;
        fieldLengths = new int[rs.Fields.Count];
        String[] fieldValues;
        fieldValues = new String[rs.Fields.Count];
        String fullString = "";

        for (i = 0; i < rs.Fields.Count; i++)
        {
            fieldLengths[i] += rs.Fields[i].DefinedSize;
            fieldValues[i] += rs.Fields[i].Value;
        }

        fullString = fileName + "," + String.Join(",", fieldValues);
        fullString = Functions.EncryptString(fullString);

        File.AppendAllText(savefile.FileName, fullString + Environment.NewLine);
        rs.MoveNext();
    }
}
catch (Exception ex)
{
}

cmd.Dispose();
// This gives me a text file of filename, fieldvalue1, fieldvalue2, etc...
// Next, I take the file to another system and run this process:

while ((myString = inputFile.ReadLine()) != null)
{
    int stringLength = myString.Length;
    String[] valuesArray = myString.Split(',');

    for (i = 0; i < valuesArray.Length; i++)
    {
        if (i == 0)
        {
            fileName = valuesArray[0];
            // Create file if it doesn't exist already
            createPhysicalFile(newLibrary, fileName);
            SQLStatement = "INSERT INTO " + newLibrary + "." + fileName + "VALUES(";
        }
        else
        {
            if (i == valuesArray.Length - 1)
            {
                SQLStatement += "@VAL" + i + ")";
            }
            else
            {
                SQLStatement += "@VAL" + i + ", ";
            }
        }
    }

    try
    {
        using (connection)
        {
            try
            {
                connection.Open();
            }
            catch (Exception ex)
            {
            }

            // Create a new SQL command
            iDB2Command command = new iDB2Command(SQLStatement, connection);

            for (i = 1; i < valuesArray.Length; i++)
            {
                try
                {
                    command.Parameters.AddWithValue("@VAL" + i, (valuesArray[i]));
                }
                catch (Exception ex)
                {

                }
            }

            // Just split the array into a string to visually check 
            // differences in the records
            String arraySplit = ConvertStringArrayToString(valuesArray);

            // The query gets executed here.  The command looks something
            // like:  
            // INSERT INTO LIBNAME.FILENAME VALUES(@VAL!, @VAL2, @VAL3, @VAL4)
            // There are actually 320 fields in the file I'm having a problem with, 
            // so it's possible I'm overlooking something.  I have narrowed it down to 
            // field # 316 when the exception occurs, but in both cases 
            // field 316 is blanks (when it works and when it doesn't).
            command.ExecuteNonQuery();
        }
    }
    catch (Exception ex)
    {
        // Here I get the exception out of bounds error in MSCORLIB.DLL. 
        // Some records are added fine, while others cause this exception.
        // I cannot visibly tell any major differences, nor do I see any  
        // errors in the AS400 job log or anything in C# that would lead me 
        // down a certain path.
        String error = ex.Message;
    }
}

Solution

  • For what it's worth, I found this happening one a smaller file in the system and was able to figure out what going on, after painstaking research into the code and the net. Basically, the file file has numeric fields on the i-series. Somehow, the records were written to the file on the original system with null values in the numeric fields instead of numeric values. When storing the original records, I had to do this calculation:

    String fieldType = rs.Fields[i].Type.ToString();
    object objValue = rs.Fields[i].Value;
    if (fieldType == "adNumeric" && objValue is DBNull)
    {
      fieldValues[i] += "0";
    }
    else
    {
      fieldValues[i] += rs.Fields[i].Value;
    }
    

    After this, if null values were found in one of the numeric fields, it just put "0" in it's place so that when writing to the new machine, it would put a valid numeric character in there and continue on writing the rest of the values. Thanks for all the advice and moral support. :)