sqlbulkcopy抛出system.formatexception运行WriteToserver(DataTable)
-
08-10-2019 - |
题
目前,我正在编写一种方法来读取从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:字符串未被识别为有效的DateTime。从索引0开始有一个未知的单词。
我进行了调试,查看所有数据已正确加载到数据表中。这是我的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
解决方案
我看到的第一个问题是,您将遇到 RowID
柱子;我希望它目前试图将您的数据倒入一列 - 它 不知道 您正在省略它。您可以弄乱映射,或者(在数据表中)添加一个 RowID
列(在索引0) - 但请注意,除非您启用身份插入,否则SQL Server将忽略该值。
也许尝试更明确的DateTime转换:
row[j] = DateTime.ParseExact(data[j], "dd/MM/yyyy", CultureInfo.InvariantCulture);
请注意,我无法从数据中分辨出是DD/mm或mm/dd,因此您可能需要对此进行调整。
其他提示
我遇到了类似的问题,列关闭了,一旦我定义了映射,就没有问题:
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);
}
另外,我有一个列表到DataTable Converter扩展程序,用于转换我的列表。
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;
}
数据文件中的字段与表不匹配,即,您正在尝试插入 DataVendorId
进入 RowId
导致异常的列,因为您无法转换 varchar(32)
到一个 int
.
将您的身份列移至表末端。现在批量插入将能够匹配所有字段 直到 它到达标识列。
不隶属于 StackOverflow