Yan*_*You 6 c# sql-server csv sqlbulkcopy sql-server-2014
这似乎是一个重复的问题。但是当我搜索和查看相关问题和答案时,我仍然找不到答案。
我正在编写一个加载程序,它将数据记录从 CSV 文件导入到数据库表中。这是演示。
数据库表如下:
use Test;
create table BoolTest (Name varchar(20) not null, IsValid bit not null);
insert into BoolTest (Name, IsValid) values('xx', 1);
insert into BoolTest (Name, IsValid) values('yy', 0);
Run Code Online (Sandbox Code Playgroud)
加载程序是这样的:
class Program
{
static void Main(string[] args)
{
var csvFileContent = "Name,IsValid\r\naa,true\r\nbb,false";
var csvLines = csvFileContent.Split(new String[] { "\r\n" }, StringSplitOptions.None);
var columnNames = csvLines[0].Split(',');
var table = new DataTable();
foreach (var columnName in columnNames)
{
table.Columns.Add(new DataColumn(columnName));
}
for (var n = 1; n < csvLines.Length; ++n)
{
var line = csvLines[n];
var values = line.Split(',');
table.Rows.Add(values);
}
var connectionString = "Data Source=localhost;Initial Catalog=Test;Integrated Security=True";
using (var bulkCopy = new SqlBulkCopy(connectionString)) {
bulkCopy.DestinationTableName = "BoolTest";
bulkCopy.ColumnMappings.Add("Name", "Name");
bulkCopy.ColumnMappings.Add("IsValid", "IsValid");
bulkCopy.WriteToServer(table);
}
Console.WriteLine("Done");
Console.Read();
}
}
Run Code Online (Sandbox Code Playgroud)
上面一切都很好。
但问题是 CSV 文件来自第 3 方,“IsValid”列的值为 0 或 1,如下所示
Name,IsValid
aa,1
bb,0
Run Code Online (Sandbox Code Playgroud)
当加载程序尝试加载此 CSV 文件时,bulkCopy.WriteToServer(table) 将抛出异常
我使用的 sql server 是 Sql server 2014。
任何帮助将不胜感激。谢谢。
- - 更新 - -
谢谢你们的解决方案。我将尝试在加载程序中手动将 0/1 更改为 false/true。但仍然想知道是否有针对此问题的简单修复(例如更改 SQL Server 或 SqlBulkCopy 中的设置)。
我也在 Sql Server Management Studio 中尝试过 sql,例如
insert into BoolTest (Name, IsValid) values('aa', 1); -- this works as we expected
insert into BoolTest (Name, IsValid) values('aa', '1'); -- this also works to my surprise
Run Code Online (Sandbox Code Playgroud)
两者都运作良好。但不确定为什么当 IsValid 值为 0 或 1 时 SQL Server 拒绝批量复制。当我们使用 'select' 显示表数据时,IsValid 的值实际上是 0 或 1。
我认为该错误是由于尝试将字符串(DataTable 中的单元格值)推入 BIT 列而引起的,因为批量插入无法执行隐式转换(“0”和“1”值转换为 0/1 BIT 值) 。
一种方法是手动定义列及其实际类型:
table.Columns.Add(new DataColumn("Name", typeof(String)));
table.Columns.Add(new DataColumn("IsValid", typeof(bool)));
Run Code Online (Sandbox Code Playgroud)
以及细胞结构如下:
for (var n = 1; n < csvLines.Length; ++n)
{
var line = csvLines[n];
var values = line.Split(',');
var rowValues = new object[values.Length];
rowValues[0] = values[0];
// conversion to integer is required as Boolean will not accept the string
rowValues[1] = Convert.ToBoolean(Convert.ToInt32(rowValues[1]));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5260 次 |
| 最近记录: |