【问题标题】:changing date format before insertion to database在插入数据库之前更改日期格式
【发布时间】:2012-05-24 17:57:13
【问题描述】:

我正在将一个 excel 文件上传到服务器,然后将其行和列插入到数据库中。我正在逐行进行,但日期时间有问题。插入 146 行数据后,我收到一条错误消息:

将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。 声明已终止。

问题在于它的日期。在 excel 文件中,日期的格式为 dd/mm/yyyy,但数据库将它们视为 mm/dd/yyyy,因此当日期超过 12 日时,我得到超出范围的错误。我不想更改我的 excel 文件,所以有没有可以在数据库(MS SQL 服务器)上更改的选项,或者我必须使用可以在插入之前转换它们的 c# 代码...谢谢...

【问题讨论】:

  • DateTime 数据类型的参数化查询将是一件好事

标签: c# sql sql-server database


【解决方案1】:

如果您知道来自 Excel 的格式,最好使用特定的 IFormatterProvider 将字符串解析为 C# 中的 DateTime。

这里的问题是来自 Excel 的字符串没有文化信息,因此转换为 DateTime 只能考虑数据库的文化 - 在这种情况下是一种反转月份和日期的格式。这意味着超出范围的日期(如您的情况)或不明确的日期将永远无法正确解析。

在 C# 代码中,您可以指定实现 IFormatterProvider 的区域性,en-GB 具有您指定的 Excel 日期的日期格式。 MSDN documentation 中的示例显示了如何执行此操作。我的示例简报展示了如何将具有 en-GB 日期格式的字符串转换为与文化无关的 DateTime

var culture = CultureInfo.CreateSpecificCulture("en-GB");
var date = DateTime.Parse("13/12/2011", culture);

SQL 在文化方面也有同样的问题。任何文化敏感数据的字符串表示将始终丢失当前文化。转换该数据时,如果它与服务器不同,则需要指定文化。

您可以在 SQL 中执行此操作,并对您尝试转换的字符串格式进行硬编码(103 表示 en-GB 日期格式 dd/mm/yyyy):

declare @datestring varchar(10) = '13/12/2011' --13th December
-- 103 is the format code for UK dates with full yyyy century.
select convert(date, @datestring, 103) --gives 2011-12-13

declare @datestring2 varchar(10) = '05/04/2011' --5th April, ambiguous date.
select convert(date, @datestring2, 103) --gives 2011-04-05

Convert / cast format codes.

还值得注意的是,这也将正确转换模糊的日期,例如 05/04/2011,如果文化未知,这将反转月/日。

例如,如果您尝试将 2011 年 4 月 5 日的英国日期转换为美国日期而不告诉解析器格式是什么,您将得到 2011 年 5 月 4 日作为输出 - 将月份和日期颠倒过来。

【讨论】:

    【解决方案2】:

    您可以在使用 T-SQL 插入之前执行此操作:

    set dateformat dmy
    

    http://msdn.microsoft.com/fr-fr/library/ms189491.aspx

    【讨论】:

      【解决方案3】:

      您也可以在数据库中执行此操作,也可以尝试编写一个存储过程,使用您的 excelsheet 将数据插入数据库。

      下面的用户在您的 SP 中提到了 TSQL 代码,这将起作用。

      CREATE PROCEDURE ABC
      AS
      -- Do some operation
          SET DATEFORMAT ydm;
      
          insert into @dates
          select '2008-09-01','2008-09-01'
      
      END
      

      【讨论】:

      【解决方案4】:

      我认为您必须在 c# 中执行此操作。 试试这样的:

      String excelDate = ...
      String[] dateParts = excelDate.Split('/');
      String sqlDate = dateParts[1] + "/" + dateParts[0] + "/" + dateParts[2];
      ...
      

      【讨论】:

        【解决方案5】:

        首先将您的 excel 日期时间解析为 C# 日期时间对象,然后将日期时间对象格式化为假设

        DateTime dt = DateTime.Parse(drExcel["dateofExcel"]);
        drDB["DateTime"] = dt.ToString("s");
        

        希望它能解决你的问题

        【讨论】:

          猜你喜欢
          • 2023-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-13
          • 2015-07-31
          • 2019-12-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多