当前位置: 首页 > 面试题库 >

Access ODBC驱动程序中无效的日期时间格式异常

解念
2023-03-14
问题内容

我有一些从ODBC驱动程序(基于DSN字符串(带有用户名和密码)选择驱动程序)读取的.NET代码,该驱动程序从表中读取多个字段,其中一个字段是DateTime字段。该代码在SQL
Server数据库/ ODBC驱动程序中的使用时间为100%,在大多数情况下,与MS
Access数据库一起使用。但是,有时我会在特定行上得到“第2列(DateTimeColumn)上无效的日期时间格式”异常,甚至没有直接访问该列的情况(例如,即使我只是调用

reader.IsDBNull(someOtherColumn)

我仍然得到例外。

这似乎主要(仅?)是在Access数据库中已经填充了Excel中计算某些DateTimes的数据(例如,将datetime加1/24以获得下一个小时)时发生的。

如果我运行以下查询,该异常消失:

UPDATE MyTable Set DateTimeColumn = CDate(CStr(DateTimeColumn))

因此,似乎从Excel的日期时间计算到Access驱动程序的日期时间计算都涉及某种舍入误差。

由于某些数据是由创建自己的数据库的用户提供的,因此我将无法使用我的代码在其数据库上运行UPDATE查询。一种可能的“仅访问”解决方法是在我的SQL语句中调用CDate(CStr(DateTimeColumn)),但这不适用于SQL
Server或其他数据库。

我仅使用可同时使用.mdb文件和.accdb文件的32位MS
Access驱动程序(我的计算机上没有64位驱动程序进行测试)对此进行了测试,并且无论是否出现问题,都会出现此问题。数据位于.mdb文件或.accdb文件中。

编辑:

为了将来参考,Date/Time导致异常的Access数据库中的值0x40E4277FFFFFFFF8以十进制为

41275.9999999999417923390865326

同样可能引起关注的是,尽管该值在尝试通过an读取行时导致错误OdbcConnection,但使用an读取同一行OleDbConnection
没有 引发异常。


问题答案:

考虑到更新后的问题中的测试数据,以下变通办法似乎可以正常工作。它检查.Driver打开的连接的属性,以查看它是否正在从Access数据库中读取。如果是这样,它将获取Date/Timeas的值Double,然后将其转换回System.DateTime。否则,它将仅从datetimeSQL
Server正常检索。

(请注意,此特定方法使用`rdr[0]) * 86400`''对于Access中早于的值(即,当值为负时) **将无法** 正常工作。)`Date/Time1899-12-30 00:00:00`Double

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Odbc;

namespace odbcTest
{
    class Program
    {
        static void Main(string[] args)
        {
            using (OdbcConnection con = new OdbcConnection())
            {
                //con.ConnectionString =
                //        @"Driver={SQL Server};" +
                //        @"Server=(local)\SQLEXPRESS;" +
                //        @"Database=myDb;" +
                //        @"Trusted_connection=yes;";
                con.ConnectionString =
                        @"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
                        @"Dbq=C:\__tmp\dateTest\TestSqlRead.accdb;";
                con.Open();
                using (OdbcCommand cmd = new OdbcCommand())
                {
                    DateTime dtm;
                    var accessTime0 = new DateTime(1899, 12, 30);
                    bool fromAccess = (con.Driver == "ACEODBC.DLL");
                    cmd.Connection=con;
                    if (fromAccess)
                        //cmd.CommandText = "SELECT DateTimeCol FROM MyTable";  // this fails
                        cmd.CommandText = "SELECT {fn CDbl(DateTimeCol)} FROM MyTable";
                    else
                        cmd.CommandText = "SELECT sqlDate FROM Table1 WHERE ID = 1";
                    OdbcDataReader rdr = cmd.ExecuteReader();
                    rdr.Read();
                    if (fromAccess)
                        dtm = accessTime0.AddSeconds(Convert.ToDouble(rdr[0]) * 86400);
                    else
                        dtm = Convert.ToDateTime(rdr[0]);
                    Console.WriteLine(dtm.ToString());
                    rdr.Close();
                }
                con.Close();
            }
            Console.WriteLine();
            Console.WriteLine("Done.");
            Console.ReadKey();
        }
    }
}


 类似资料:
  • 问题内容: 我想向Access插入一个datetime值,但是出现此错误: net.ucanaccess.jdbc.UcanaccessSQLException:UCAExc ::: 3.0.4数据异常:无效的日期时间格式 这是代码: 问题答案: 错误消息表明您的方法最终试图做类似的事情 并且由于以下两个原因将无法正常工作: UCanAccess希望日期文字被括在井号()中,并且 UCanAcce

  • 当我尝试在日期格式选项中使用正确的数据(包括时间,例如:2018-01-01 07:00:00))添加或编辑新行时,我尝试在日期格式选项中使用“newform: Y-m-d H: i: s”总是返回无效的日期警告。 有人能帮我把它正常工作吗? JSFIDLE:链接

  • 下表显示可用于为图表中的日期时间字段创建用户定义的数据格式的说明符。 说明符 描述 D 将日显示为不带前导零的数字(1-31)。 DD 将日显示为带前导零的数字(01-31)。 M 将月份显示为不带前导零的数字(1-12)。 MM 将月份显示为带前导零的数字(01-12)。 MMM 将月份显示为缩写形式(Jan-Dec)。 MMMM 将月份显示为完整月份名(January-December)。 Y

  • 下表显示可用于为图表中的日期时间字段创建用户定义的数据格式的说明符。 说明符 描述 D 将日显示为不带前导零的数字(1-31)。 DD 将日显示为带前导零的数字(01-31)。 M 将月份显示为不带前导零的数字(1-12)。 MM 将月份显示为带前导零的数字(01-12)。 MMM 将月份显示为缩写形式(Jan-Dec)。 MMMM 将月份显示为完整月份名(January-December)。 Y

  • 下表显示可用于为图表中的日期时间字段创建用户定义的数据格式的说明符。 说明符 描述 D 将日显示为不带前导零的数字(1-31)。 DD 将日显示为带前导零的数字(01-31)。 M 将月份显示为不带前导零的数字(1-12)。 MM 将月份显示为带前导零的数字(01-12)。 MMM 将月份显示为缩写形式(Jan-Dec)。 MMMM 将月份显示为完整月份名(January-December)。 Y

  • 我有一个关于格式化程序的问题。 在SWAPI(https://SWAPI.co/documentation#people)中,您可以读取和日期,其格式如下: 但是在预定义格式化程序中的类DateTimeFormatter的文档一节中,我看不到任何与SWAPI日期示例匹配的格式化程序。