C# SQL Bulkcopy YYYYMMDD问题

C# SQL Bulkcopy YYYYMMDD问题,c#,date,sqlbulkcopy,C#,Date,Sqlbulkcopy,我在asp.net 3.5和C中使用SQL Bulkcopy时遇到字符串到日期的转换问题# 我读了一个大的CSV文件(带有)。读取的字符串之一应加载到SQL server 2008日期列中 如果文本文件包含字符串“2010-12-31”,则SQL Bulkcopy会将其毫无问题地加载到日期列中 但是,如果字符串是'20101231',我会得到一个错误: 数据源中类型字符串的给定值无法转换为指定目标列的类型日期 该文件包含8000万条记录,因此我无法创建datatable SqlBulkcopy列

我在asp.net 3.5和C中使用SQL Bulkcopy时遇到字符串到日期的转换问题#

我读了一个大的CSV文件(带有)。读取的字符串之一应加载到SQL server 2008日期列中

如果文本文件包含字符串“2010-12-31”,则SQL Bulkcopy会将其毫无问题地加载到日期列中

但是,如果字符串是'20101231',我会得到一个错误:
数据源中类型字符串的给定值无法转换为指定目标列的类型日期

该文件包含8000万条记录,因此我无法创建datatable

SqlBulkcopy列映射等都可以。同时,更改为DateTime也无济于事

我试过了

SET DATEFORMAT ymd;
但这没有帮助

你知道如何告诉SQLServer接受这种格式吗?否则,我将在CSV阅读器中创建一个自定义修复程序,但我更喜欢SQL

更新 继这两个答案之后,我使用SQL bulkcopy如下(正如在另一个问题中针对Stackoverflow提出的):

CSV阅读器(请参阅上面关于codeproject的链接)返回字符串值(不是强类型)。CSVreader实现System.Data.IDataReader,因此我可以执行以下操作:

using (CsvReader reader = new CsvReader(path)) 
using (SqlBulkCopy bcp = new SqlBulkCopy(CONNECTION_STRING))
{ bcp.DestinationTableName = "SomeTable"; 
  // columnmappings
  bcp.WriteToServer(reader); } 
来自iDataReader的所有字段都是字符串,因此我不能使用c#方法,除非我在CSVRReader中做了大量更改

因此,我的问题与如何在C#中修复它无关,我可以这样做,但我想阻止它

这很奇怪,因为如果在sql中执行

 update set [somedatefield] = '20101231' 
它也可以工作,只是不适用于bulkcopy

知道为什么吗

谢谢你的建议,
请不要将数据以字符串格式上载到SQL Server:将其解析为CSV读取器中的
日期时间
日期时间偏移量
(或CSV读取器的输出),然后以这种方式上载。那么你就不必担心字符串格式了。

如果你能用C#本身来处理它,那么这段代码将有助于把字符串中的日期作为DateTime对象,你可以直接传递它

//datestring is the string read from CSV
DateTime thedate = DateTime.ParseExact(dateString, "yyyyMMdd", null);
如果要将其格式化为字符串,则:

string thedate = DateTime.ParseExact(dateString, "yyyyMMdd", null).ToString("yyyy-MM-dd");
祝你好运

更新

在您的场景中,我不知道为什么日期不是自动格式化的,而是从C开始的,您需要进入并干预将数据传递到
WriteToServer()
方法的过程。我认为您能做的最好的事情(记住性能)是缓存DataRow项并将它们传递给方法。我将在一分钟内编写示例代码

//A sample code.. polish it before implementation
//A counter to track num of records read
long records_read = 0;
While(reader.Read())
{
    //We will take rows in a Buffer of 50 records
    int i = records_read;//initialize it with the num of records last read
    DataRow[] buffered_rows = new DataRow[50];
    for(;i<50 ;i++)
    {
        //Code to initialize each rows with the data in the reader
        //.....
        //Fill the column data with Date properly formatted
        records_read++;
        reader.Read();
    }
    bcp.WriteToServer(buffered_rows);
}
//示例代码。。在实施之前对其进行润色
//用于跟踪读取记录数的计数器
长记录读取=0;
While(reader.Read())
{
//我们将在50条记录的缓冲区中获取行
int i=records\u read;//使用上次读取的记录数初始化它
DataRow[]缓冲的_行=新DataRow[50];

对于(;i较旧的问题,但希望添加另一种方法

当从IDataReader流式传输时,SQLBulkLoader不允许列的数据类型/区域性规范也存在同样的问题

为了减少在本地构建数据行的速度开销,而不是在目标上进行解析,我使用的一个简单方法是将线程区域性临时设置为定义所用格式的区域性—在本例中为US格式日期

对于我的问题-输入中的en US日期(在Powershell中):


我发现允许数据库服务器在通过SQLBulkCopy接口后执行类型转换要比在本地执行解析快得多,尤其是在脚本语言中。

谢谢你的帮助,但如上所示,如果没有CSV阅读器中的重大更新,我无法在C中执行转换。现在这是一个奇怪的问题avior但正如@Jon所说,您需要咬紧牙关,进入将数据传递给writetoserver方法的过程。我更新了这个问题,并简要解释了如何使用SqlBulkCopy。我知道这并不理想,但CSV阅读器只返回字符串(对于8000万行,如果SQL Server直接接受它们就好了)。这很奇怪,因为如果执行sql更新集[somedatefield]='20101231'它也可以工作,只是不能与bulkcopy一起工作。@Pleun:我敢说有一种方法可以将它弄坏-但如果我是你,我会咬紧牙关自己执行转换。将每个值都设置为适当的类型是一个更好的解决方案-这意味着你可以在客户端级别尽早执行验证。多亏了你们两位-我会按照你的建议去做,咬紧牙关。哈哈..你咬紧牙关;-)
[System.Threading.Thread]::CurrentThread.CurrentCulture = 'en-US'
<call SQLBulkCopy>
CultureInfo newCulture = (CultureInfo) System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
newCulture.DateTimeFormat.ShortDatePattern = "yyyyMMDD;
Thread.CurrentThread.CurrentCulture = newCulture;