【问题标题】:SQL Server - can't import value 0 or 1 to bit columnSQL Server - 无法将值 0 或 1 导入位列
【发布时间】:2016-09-04 21:49:00
【问题描述】:

这似乎是一个重复的问题。但是当我搜索和查看相关问题和答案时,我仍然找不到答案。

我正在编写一个加载程序,它将数据记录从 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);

加载程序是这样的:

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();
    }
}

上面一切都很好。

但问题是 CSV 文件来自第 3 方,“IsValid”列的值为 0 或 1,如下所示

Name,IsValid
aa,1
bb,0

当加载程序试图加载这个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

两者都运作良好。但不知道为什么当 IsValid 值为 0 或 1 时 SQL 服务器会拒绝批量复制。当我们使用 'select' 显示表数据时,IsValid 的值实际上是 0 或 1。

【问题讨论】:

  • 尝试 TRUE,FALSE 而不是 1,0。
  • @AbdulRasheed 是的,真/假对程序来说是可以的。但 csv 文件来自另一家公司,值为 0/1。
  • @yyou 然后你需要告诉他们用true/false 发送它,或者你需要让你的程序根据需要替换这些值。
  • 你能找到一种在插入之前将字符串解析为整数的方法吗?我认为 CSV 阅读器正在将值读取为字符串而不是整数,例如“1”而不是 1
  • 可能是批量复制。这使用了一个快速的特殊 API - 但绕过了 SQL Server 通常应用的许多逻辑。它们之间的类型转换。

标签: c# sql-server csv sql-server-2014 sqlbulkcopy


【解决方案1】:

这是因为布尔值在插入时被位值替换,为了让我们的生活更容易解决这个问题,您只需要创建一个将位转换为布尔值的解析方法,足够简单。然后应该工作

【讨论】:

    【解决方案2】:

    我认为错误是由于尝试将字符串(DataTable 中的单元格值)推送到 BIT 列引起的,因为批量插入无法执行隐式转换(“0”和“1”值到 0/1 BIT 值)。

    一种方法是手动定义列及其实际类型:

    table.Columns.Add(new DataColumn("Name", typeof(String)));
    table.Columns.Add(new DataColumn("IsValid", typeof(bool)));
    

    细胞构造如下:

    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]));
    }
    

    【讨论】:

      【解决方案3】:

      以下INSERT 语句将在SQL 级别上工作:

      INSERT INTO BoolTest (Name, IsValid) VALUES ('xx', 1);
      INSERT INTO BoolTest (Name, IsValid) VALUES ('yy', 0);
      

      但是当您将值传递给存储过程或 SQL 语句时,您不能传递 0 或 1,因为它将作为 0 或 1 传递(并被接受)。它需要是真或假才能通过。

      我认为这是您拆分行值的地方:

      var values = line.Split(',');
      

      您需要做的就是测试 0 和 1,然后分别用 false 或 true 替换它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-18
        • 1970-01-01
        • 1970-01-01
        • 2010-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-01
        相关资源
        最近更新 更多