2

(A) という名前の列を含むテーブルがありますconfirmation_number。として定義され、 のvarchar2(30)ようなものが含まれていますSMITERI-2012-02-31-4567

(B)という名前の列も含む別のテーブルがconfirmation_numberあり、それもvarchar2(30).

からデータを抽出しA、それに何らかの変換を実行するストアド プロシージャがあり、確認番号列が含まれています。

C#andを使用しODP.Netてストアド プロシージャを実行し、それをロードDataTableします。次に、いくつかの追加の変換を実行します。ただし、確認番号欄には一切触れません。

最後に、OracleBulkCopyオブジェクトを作成し、列のマッピングを設定し、それをupdateTableに伝えてB、 を呼び出しますloader.WriteToServer(dataTable)

次のエラーが表示されます

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

confirmation_numberその列をロードしなければ、データロードは成功するため、列でエラーが発生することを確認しました。

BulkCopyが を に変えようとする理由はvarchar(2)ありNumberますか?

編集: 次の関連する問題を確認しました。

  1. これは、確認番号以外にも発生しています。これは、文字列から文字列へ、または文字列から整数へのいずれであっても、文字列列でのみ問題になるようです。

  2. これはすべての varchar2 列で発生するわけではありません - 姓と名には問題ありません。

  3. これは、NULL 値を持たない列 (確認番号) と、NULL 値を持つ可能性がある列 (ストリート タイプ) の両方で発生します。

  4. ローダーが開始される前の瞬間にデータテーブルの内容を調査すると、正常に入る列とそうでない列の間で列定義に違いは見られません。

BulkCopy 自体にバグがあるのではないか、別のユーティリティを使用してこの読み込みを行う必要があるのではないかと考え始めています。

編集:

以下は、トリミングされたコードです。

表 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")

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

データの取得

            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"];

列マッピングを設定する

 private static Dictionary<string, string> ColumnMappings()
    {
        Dictionary<string, string> mapping = new Dictionary<string, string>();
        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;
    }

ファイルの読み込み

 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<string, string> k in ColumnMappings())
                    {
                        loader.ColumnMappings.Add(k.Key, k.Value);
                    }

                    loader.WriteToServer(dt);

                } //end using oracle bulk loader

            } //end using oracle connection

        }

編集: 一括コピーを機能させることができませんでしたが、配列を使用して機能させる従来の方法を取得しました: http://www.oracle.com/technetwork/issue-archive/2009/09-sep/o59odpnet- 085168.html

一括読み込みが成功するよりも確実に遅くなりますが、少なくともデータを取得することはできます。ただし、一括コピー自体が失敗し続ける理由について何か考えがある人がいれば幸いです。

4

2 に答える 2

1

指定されBulkCopyた列の宣言された型に基づいて、ある種の型変換を行うDataTableようです。

問題の原因となっている列を出力Column.DataType.ToString()すると、データベースが期待するタイプ以外のタイプが表示される可能性が高くなります。

古いデータテーブルを使用して新しいデータテーブルを作成できますがColumn.DataType、問題のある列をデータベースが期待するタイプになるように明示的に変更します。

public DataTable potentialFix(DataTable dt) {    
    DataTable newTable = new DataTable(dt.TableName);

    //define columns for the new table with type string (or whatever type you want)
    foreach (DataColumn dc in dt.Columns)
    {
        newTable.Columns.Add(new DataColumn(dc.ColumnName, typeof(String)));
    }

    newTable.BeginLoadData();
    DataTableReader dtReader = new DataTableReader(dt);
    newTable.Load(dtReader);
    newTable.EndLoadData();

    return newTable;
}
于 2012-08-06T20:02:24.623 に答える
0

問題は「date_of_birth」列にあると思います。日付ではなく文字列を渡しています。日付は数値であるため、キャストしようとしますが、期待する形式ではありません。月と日の順序が変更されました。

于 2012-04-11T06:27:09.770 に答える