【问题标题】:C# SqlCommand Inserting Null ValuesC# SqlCommand 插入空值
【发布时间】:2014-01-06 14:08:50
【问题描述】:

我有一个 CSV 文件,其中包含大约 400 万行干净数据,我需要将其导入 SQL Server 2008 R2 数据库。

我尝试仅通过 TSQL、SSIS 和其他一些方法来执行此操作,但最后我总是遇到同样的问题,每行有 2,000 多列。 SQL Server 在读取 CSV 文件中的那么多列时遇到问题。

因此,我最终编写了一个小 C# 控制台程序来解析 csv 文件,并完成所有工作以将 2,000 多列分解到我数据库中的关系表中。一切都运行良好,但 CSV 文件有 400 万行,效率是关键。

说了这么多,这就是我遇到的问题,而且我一生都无法弄清楚。我正在使用旧的 SqlCommand 类进行批量插入。我不知道如何将空值输入数据库。例如,采取这一行

var PreparedCommand = "insert into person_modeling_info (person_id, modeling_info,     response) values "; 

PreparedCommand += "( " + info[0] + ",'" + info[1] + "'," + (item2.Value == "" ? "'NULL'" : "'"+item2.Value+"'") + "),";

我不担心 SQL 注入,因为我 100% 确定数据是干净的。我知道我可以使用参数插入 null,但参数较慢,因为我必须一次插入一条记录,而不是像进行批量插入一样 insert into table (values), (values), (values)

当我使用连接执行插入时,它会作为空字符串插入到数据库中。

如果有人有想法,任何帮助将不胜感激。

【问题讨论】:

  • 我不担心 SQL 注入你应该我的朋友,你应该..
  • 为什么,它将数据从内部的一个系统移动到内部的另一个系统。
  • NULL 不带引号应该可以。当然,注入问题仍然存在。
  • "'NULL'" 产生字符串 NULL,删除单引号作为其 DB 关键字

标签: c# sql sql-server


【解决方案1】:

您确定 item2.Value 还没有 == null 吗?你试过了吗:

PreparedCommand += "( " + info[0] + ",'" + info[1] + "'," + (item2.Value == null ? "'NULL'" : "'"+item2.Value+"'") + "),";

【讨论】:

  • 我建议使用String.IsNullOrEmpty 而不是简单的空检查(鉴于您正在做的是改变空字符串的行为)但是是的,这似乎是一个合理的解释。跨度>
  • @Chris:在数据库中,就像在 C# 中一样,null'' 是不同的。
  • @Andomar:是的,但用户当前将空字符串视为与 null 相同,因此我倾向于保留该行为,同时检查 null 而不是在没有明确的情况下更改现有行为标记它。如果用户在输入空字符串时也遇到问题,那么我相信他会说的。
【解决方案2】:

你应该这样尝试:

您必须从'NULL' 中删除单引号,还要检查item2.Value 是否为空或为空。

var PreparedCommand = "insert into person_modeling_info (person_id, modeling_info,     response) values "; 

    PreparedCommand += "( " + info[0] + ",'" + info[1] + "'," + ( string.IsNullOrEmpty(item2.Value)==true?  "NULL" : "'"+item2.Value+"'") + "),";

【讨论】:

    【解决方案3】:

    您可以使用相同的想法使您的插入列有条件:

    var PreparedCommand = "insert into person_modeling_info (person_id, modeling_info" + (item2.Value == "" ? "" : ",response") + ") values "; 
    
    PreparedCommand += "( " + info[0] + ",'" + info[1] + "'" + (item2.Value == "" ? "" : ",'"+item2.Value+"'") + "),"; 
    

    最好使用 SQL 参数并使用 DbNull.Value

    【讨论】:

    • 对,我最初尝试过,但速度较慢,因为这样做需要我单独插入每一行。当我使用批量插入进行 shudder 字符串连接时,它的运行时间缩短了大约 40 秒。
    【解决方案4】:

    使用SqlParameters 并分配DbNull.Value。真的,没有任何借口。在这样的公共论坛上发布 SQL 注入代码是违法的。两年后,一些无辜的白痴会复制/粘贴它......

    当然,有效地从 CSV 移动 4M 行确实是关于 bcp.exeSSIS 或最坏的情况下是 SqlBulkCopy 的问题。我建议阅读The Data Loading Performance Guide 并了解Operations That Can Be Minimally Logged

    【讨论】:

    • 这不是冒犯,你错了。我不是白痴,我很清楚它是易受 SQL 注入攻击的。但是,我并不担心,因为这个程序只是将 CLEAN 数据从内部平面文件移动到关系数据库中。
    猜你喜欢
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    相关资源
    最近更新 更多