I have a table (A)  that includes a column named confirmation_number.  It is defined as a varchar2(30) and contains something like SMITERI-2012-02-31-4567.

I have another table (B) that also includes a column named confirmation_number, and it is also a varchar2(30).

I have a stored procedure that extracts the data from A, performing some transformation on it, and it includes the confirmation number column.  

I use C# and ODP.Net to run the stored procedure and load a DataTable with it.  I then perform some additional transformations.  However, I never touch the confirmation number column.

Finally, I create an OracleBulkCopy object, set the column mappings, tell it to update Table B, and call loader.WriteToServer(dataTable).

I am getting the following error:

Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer&amp; number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt)
   at Oracle.DataAccess.Client.OracleBulkCopy.PerformBulkCopy()


I have confirmed that the error occurs on the confirmation_number column, because if I don't load that column, the dataload succeeds.

Any ideas why the BulkCopy would be trying to turn a varchar(2) into a Number?

EDIT:
I have confirmed the following relevant issues:


This is happening on more than just the confirmation number.  This
appears to only be a problem on string columns - whether from a
string to a string or a string to an integer. 
This doesn't happen on every varchar2 column - last name and first name have no trouble.
This happens both on columns that have no null values (confirmation
number) and on columns that may have null values (street type).
Investigating the contents of the datatable at the moment before the
loader begins shows no difference in column definition between those
that successfully go in and those that do not.


I'm beginning to wonder if there's a bug in the BulkCopy itself and if I need to do this load using another utility.

EDIT: 

Below is the trimmed down code.

Table A

  CREATE TABLE "APPS_UNPROCESSED" 
   (    "LAST_NAME" VARCHAR2(30 BYTE), 
    "FIRST_NAME" VARCHAR2(30 BYTE), 
    "MIDDLE_NAME" VARCHAR2(30 BYTE), 
    "NAME_SUFFIX" VARCHAR2(30 BYTE), 
    "GENDER" VARCHAR2(1 BYTE), 
    "DATE_OF_BIRTH" VARCHAR2(10 BYTE), 
    "ID" NUMBER, 
     :
     :
    "CONFIRMATION_NUMBER" VARCHAR2(30 BYTE) NOT NULL ENABLE, 
    "IS_FBO" NUMBER(1,0), 
     :
     :
     CONSTRAINT "VR_APPS_UNPROCESSED_PK" PRIMARY KEY ("CONFIRMATION_NUMBER")


Table B

  CREATE TABLE "APPS_PROCESSED"
   (    "LAST_NAME" VARCHAR2(30 BYTE), 
    "FIRST_NAME" VARCHAR2(30 BYTE), 
    "MIDDLE_NAME" VARCHAR2(30 BYTE), 
    "NAME_SUFFIX" VARCHAR2(30 BYTE), 
    "GENDER" NUMBER(1,0), 
    "DATE_OF_BIRTH" DATE,
     :
     :
    "CONFIRMATION_NUMBER" VARCHAR2(30 BYTE), 
    "ID" NUMBER, 
    "IS_FBO" NUMBER(1,0),
     :
     :
    "ID" NUMBER NOT NULL ENABLE, 
     :
     :
     CONSTRAINT "VR_APPLICATION_PK" PRIMARY KEY ("ID")


Procedure

 procedure getUnprocessedApps(results OUT sys_refcursor)
   as
   BEGIN
    open results for
      select 
        a.last_name
        ,a.first_name
        ,a.middle_name
        ,a.name_suffix
        ,decode(a.gender, 'M', 1, 0) as gender_id
        ,a.gender as gender_code
        ,to_char(to_date(a.date_of_birth, 'MM-DD-YYYY'), 'DD-mon-YYYY') as date_of_birth
        ,cast(a.confirmation_number as varchar2(30)) as confirmation_number
        ,a.id
        ,0 as is_fbo
     :
     :
      from vr_apps_unprocessed a


fetching the data

            DataSet data = new DataSet();
                OracleConnection conn = null;
                OracleCommand cmd = null;
                OracleDataAdapter data_adapter = new OracleDataAdapter();


                //fetch the data and load
                using (conn = new OracleConnection(connString))
                {
                    using (cmd = new OracleCommand())
                    {

                        cmd.Connection = conn;
                        cmd.CommandText = "APPS.getUnprocessedApps";
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.Add("results", OracleDbType.RefCursor, ParameterDirection.Output);
                        conn.Open();
                        data_adapter.SelectCommand = cmd;
                        data_adapter.Fill(data, "results");
                    }
                }
                return data.Tables["results"];


setup the column mapping

 private static Dictionary&lt;string, string&gt; ColumnMappings()
    {
        Dictionary&lt;string, string&gt; mapping = new Dictionary&lt;string, string&gt;();
        mapping.Add("last_name", "last_name");
        mapping.Add("first_name", "first_name");
        mapping.Add("middle_name", "middle_name");
        mapping.Add("name_suffix", "name_suffix");
        mapping.Add("gender_id", "gender"); 
        mapping.Add("date_of_birth", "date_of_birth");
        mapping.Add("is_fbo", "is_fbo"); 
        mapping.Add("confirmation_number", "confirmation_number");
        mapping.Add("id", "id"); 
     :
     :
            return mapping;
    }


Load files

 private static void loadFiles(DataTable dt, string connString)
        {
            OracleConnection orclconn = null;
            OracleBulkCopy loader = null;

            //now insert the data into Oracle               
            using (orclconn = new OracleConnection(connString))
            {
                orclconn.Open();
                using (loader = new OracleBulkCopy(orclconn)) 
                {
                    loader.DestinationTableName = "APPS_Processed"

                    foreach (KeyValuePair&lt;string, string&gt; k in ColumnMappings())
                    {
                        loader.ColumnMappings.Add(k.Key, k.Value);
                    }

                    loader.WriteToServer(dt);

                } //end using oracle bulk loader

            } //end using oracle connection

        }


EDIT:
I have been unable to get the bulkcopy to work, but I have gotten the traditional method of using arrays to work: http://www.oracle.com/technetwork/issue-archive/2009/09-sep/o59odpnet-085168.html

It is definitely slower than a successful bulk load, but at least I can get the data in.  I'd still love if anyone has any ideas on why the bulkcopy itself keeps failing, though.


Question: Bug in my C code to reverse words in a string
Answer: I think that you want to reverse words in a string, not reverse the whole string and then rereverse single words. So, delete first reverse and then apply suggested changes above.

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

void reverse(char*, int);

int main(int argc, char **argv)
{
  char st[]= "hello world";
  int i=0, j=0;

  while(st[j]){ //Loop till end of the string
    if ( st[j] == ' ') { //if you hit a blank space or the end of the string
      reverse(&amp;st[i], j - i - 1); // reverse the string starting at position i till position before the blank space i.e j-1
      i = ++j; //new i &amp; j are 1 position to the right of old j
    }
    else {
      j++; //if a chacacter is found, move to next position
    }               
  }
  reverse(&amp;st[i], j - i - 1);


  printf("%s\n",st);
  return 0;
}

void reverse(char *s, int n)
{
  char *end = s + n; //end is a pointer to an address which is n addresses from the    starting address
  char tmp;

  while (end &gt; s)  //perform swap
  {
    tmp = *end;
    *end = *s;
    *s = tmp;
    end--;
    s++;
  }
}


Take care when input string would be '\0' or something like ' Hello world'. Above code doesn't managed this kind of situations. Think about it!