4

我在 SQL Server 中有一个链接表,其中包含一个日期时间列,我在其中存储了一个仅限时间的值*。如果我在没有 dbFailOnError 的情况下执行 UPDATE 查询,它会将该命令转换为 SELECT,然后是一次执行一行的单个 UPDATE 语句:

exec sp_executesql N'UPDATE "dbo"."Appeals" SET "HearingTime"=@P1 
                     WHERE "AppealID" = @P2'
                  ,N'@P1 datetime,@P2 int','1899-12-30 09:00:00',1
...
exec sp_executesql N'UPDATE "dbo"."Appeals" SET "HearingTime"=@P1 
                     WHERE "AppealID" = @P2'
                  ,N'@P1 datetime,@P2 int','1899-12-30 09:00:00',4

如果我执行完全相同的 UPDATE 查询,但使用 dbFailOnError,我会得到以下翻译:

UPDATE "dbo"."Appeals" SET HearingTime={t '09:00:00'} 

有趣的是 dbFailOnError 在后端强制执行更有效的 UPDATE,但我真正关心的是时间值本身。

在第一个示例中,Access 正确地将日期时间设置为 12/30/1899(MS Access 的神奇“零”日)。在第二种情况下,这不会发生。最终结果是第一个示例“有效”,而第二个示例无效。

我的意思是,如果我在数据表视图中查看HearingTime字段,Access 会将第一个字段显示为:

9:00:00 AM

第二个显示为(截至撰写本文时,2016 年 9 月 3 日是今天的日期):

9/3/2016 9:00:00 AM

我不得不假设这是微软的一个错误。或者我在这里错过了什么?我有比报告错误并希望微软有朝一日修复它更好的选择吗?


*是的,我知道timeSQL Server 中有一个数据类型。它与 MS Access 日期时间类型不兼容,因此在 MS Access 链接表中对我来说用处不大。

4

2 回答 2

4

我能够使用带有 Access SQL 日期/时间文字的查询来重现您的问题。两个都

Dim cdb As DAO.Database
Set cdb = CurrentDb
cdb.Execute "UPDATE dbo_Appeals SET HearingTime=#10:00:00#", dbFailOnError

Dim cdb As DAO.Database
Set cdb = CurrentDb
cdb.Execute "UPDATE dbo_Appeals SET HearingTime=#1899-12-30 11:00:00#", dbFailOnError

导致当前日期(2016-09-03)的 [HearingTime] 值,而不是“零”日期。

但是,将完整的日期/时间作为字符串传递似乎可行

Dim cdb As DAO.Database
Set cdb = CurrentDb
cdb.Execute "UPDATE dbo_Appeals SET HearingTime='1899-12-30 12:00:00'", dbFailOnError

(省略字符串值中的日期部分会导致 [HearingTime] 值的 SQL Server DATETIME“零”日期为 1900-01-01。)

而且,更好的是,带有DAO.QueryDef对象的参数化查询似乎也可以正常工作

Dim cdb As DAO.Database
Set cdb = CurrentDb
Dim qdf As DAO.QueryDef
Set qdf = cdb.CreateQueryDef("", _
        "PARAMETERS prmHearingTime DateTime;" & _
        "UPDATE dbo_Appeals SET HearingTime=[prmHearingTime]")
qdf!prmHearingTime = #10:00:00 AM#
qdf.Execute dbFailOnError
于 2016-09-03T12:02:25.043 回答
0

这是一个很好的问题,我可以重现它。

这似乎是 ODBC 驱动程序中的一个错误,因为您演示的行为是 ODBC 驱动程序应该补偿的 SQL Server 行为,就像在您的第一个示例中一样,它通过提供完整的日期时间字符串来在读取时正确转换回到访问。

除了在您回读数据时将TimeValue应用于日期时间值之外,我看不出有什么办法可以解决这个问题。但是,这将停止使用您的时间字段的索引。

SQL Server 的数据类型Time不能用于许多事情,因为 ODBC 驱动程序将这些读取为文本。

于 2016-09-03T12:01:33.890 回答