4

現在、CSVファイルからデータを読み取り、SQLテーブルにインポートするメソッドを作成しています。

        DataTable dt = new DataTable();
        String line = null;
        int i = 0;

        while ((line = reader.ReadLine()) != null)
        {
            String[] data = line.Split(',');
            if (data.Length > 0)
            {
                if (i == 0)
                {
                    foreach (object item in data)
                    {
                        DataColumn c = new DataColumn(Convert.ToString(item));
                        if (Convert.ToString(item).Contains("DATE"))
                        {
                            c.DataType = System.Type.GetType("System.DateTime");
                        }
                        else { c.DataType = System.Type.GetType("System.String"); }
                        dt.Columns.Add(c);
                    }
                    i++;
                }
                else
                {
                    DataRow row = dt.NewRow();
                    for (int j = 0; j < data.Length; j++)
                    {
                        if (dt.Columns[j].DataType == System.Type.GetType("System.DateTime"))
                        {
                            row[j] = Convert.ToDateTime(data[j]);
                        }
                        else
                        {
                            row[j] = data[j];
                        }
                    }
                    dt.Rows.Add(row);
                }
            }
        }
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings[Constant.CONNECTION_STRING_NAME].ConnectionString);
        SqlBulkCopy s = new SqlBulkCopy(con);
        s.DestinationTableName = "abc";
        con.Open();
        s.WriteToServer(dt);

このメソッドを実行するときの問題は、常にs.WriteToServer(dt)で例外がスローされることです。言って

System.FormatException:文字列が有効な日時として認識されませんでした。インデックス0から始まる不明な単語があります。

デバッグして、すべてのデータがDataTableに正しく読み込まれていることを確認しました。これが私のCSVファイルのデータ行の例です

DATA_VENDOR_ID,DATA_VENDOR_SUB_ID,DATA_VENDOR_CLIENT_ID,DATA_VENDOR_ACTIVITY_CODE,ACTIVITY_NAME,EFFECTIVE_DATE,ACTIVITY_LEVEL1,ACTIVITY_LEVEL2,ACTIVITY_LEVEL3,ACTIVITY_LEVEL4,ACTIVITY_LEVEL5,PARTICIPANT_ID,DATA_VENDOR_ALT_ID,FILE_CREATION_DATE,INC_VALUE    
V01,,22097,ABCD01,Physical Activity,10/01/2010,Entertain Kiosk,ABCD - EFG 54,30,,AB01,W1234567891,,08/07/2006,100

と私のSQLテーブルスキーマ:

RowID   int Unique/AutoIncrement
DataVendorId    varchar(32) 
DataVendorSubId varchar(32) 
DataVendorClientId  varchar(32) 
DataVendorActivityCode  varchar(32) 
ActivityName    varchar(64) 
EffectiveDate   datetime    
ActivityLevel1  varchar(253)    
ActivityLevel2  varchar(253)    
ActivityLevel3  varchar(253)    
ActivityLevel4  varchar(253)    
ActivityLevel5  varchar(253)    
ParticipantID   varchar(32) 
DataVendorAltId varchar(32) 
FileCreationDate    datetime    
IncValue    varchar(5)  
CreatedDate datetime    optional/allow null
ModifiedDate    datetime    optional/allow null
4

3 に答える 3

2

私が最初に目にする問題は、RowID列に問題が発生することです。現時点では、データを1列オフセットしようとしていると思います。データを省略していることはわかりません。マッピングを混乱させるか、(データテーブルで)RowID列を(インデックス0に)追加することができますが、ID挿入を有効にしない限り、SQLServerは値を無視することに注意してください。

おそらく、より明示的な日時変換を試してください。

row[j] = DateTime.ParseExact(data[j], "dd/MM/yyyy", CultureInfo.InvariantCulture);

データからはdd/MMなのかMM/ddなのかわからないので、微調整が必​​要な場合があります。

于 2010-11-12T06:29:16.163 に答える
1

列がオフであるという同様の問題があり、マッピングを定義したら問題はありませんでした。

using (SqlBulkCopy sbc = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["SQLDatabase"].ConnectionString, SqlBulkCopyOptions.KeepIdentity))
            {
                sbc.DestinationTableName = "DestinationTable";
                sbc.ColumnMappings.Add("foo", "bar");
                sbc.ColumnMappings.Add("hello", "world");
                sbc.ColumnMappings.Add("col1", "col2");
                sbc.WriteToServer(data);
            }

また、List を変換するために使用する List to DataTable コンバーター拡張機能もあります。

public static DataTable ToDataTable<T>(this IEnumerable<T> data)
        {
            PropertyDescriptorCollection properties =
                TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            foreach (T item in data)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = GetDataValue(prop.GetValue(item));
                table.Rows.Add(row);
            }
            return table;
        }

GetDataValue() メソッドは、MinValue 日付などのデータをクリーンアップします。

private static object GetDataValue(object value)
        {
            if (value == null || (value.GetType() == typeof(DateTime) && Convert.ToDateTime(value) == DateTime.MinValue) || (value.GetType() == typeof(DateTime) && Convert.ToDateTime(value) < Convert.ToDateTime("01/01/1753")))
            {
                return DBNull.Value;
            }

            return value;
        }
于 2013-04-10T14:30:15.673 に答える
0

データ ファイルのフィールドがテーブルと一致しません。つまり、 を列に挿入しようとすると、DataVendorIdを に変換RowIdできないため、例外が発生します。 varchar(32)int

ID 列をテーブルの最後に移動します。これで、一括挿入は、識別列に到達するまですべてのフィールドを照合できるようになります。

于 2012-01-19T15:46:14.063 に答える