【问题标题】:Is is possible to update SQL Server 2016 temporal tables from Access?是否可以从 Access 更新 SQL Server 2016 时态表?
【发布时间】:2016-08-09 21:48:43
【问题描述】:

我创建了一个带有临时表 Product 的 SQL Server 2016 数据库。我想通过链接表从 Access 数据库中更新表。尝试执行此操作时,Access 会报告

保留错误(-7776):没有针对此错误的错误消息

表定义为:

CREATE TABLE [dbo].[Product]
(
    [Product] [uniqueidentifier] NOT NULL,
    CONSTRAINT PK_Product_Product PRIMARY KEY CLUSTERED (Product),
    [Name] [nchar](50) NOT NULL,
    CONSTRAINT [AK_Product_Name] UNIQUE([Product line], [Name]),
    [Status] [uniqueidentifier] NOT NULL,
    SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL,
    SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL,
    PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)     
) ON [PRIMARY] WITH    
   (   
      SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.ProductHistory)   
   ) 
GO

查询

UPDATE Product 
SET Status = (SELECT [Product status] 
              FROM [Product status]
              WHERE [Name] = 'Announced') 
WHERE [Name] = 'A300';

成功且没有错误,并显示在 Access 表中。更新会正确反映在历史记录表中。

我已尝试隐藏有效时间列,以防它们的后端更改导致问题,但没有效果。 ProductProduct status 表都包含最少的数据。

是否有一些特定的方法可以让它工作,还是不支持这种情况?

【问题讨论】:

  • 您到时态表的 ODBC 链接是否使用 SQL Server 的最新 ODBC 驱动程序?
  • 您可以尝试在此表上创建一个没有问题列的视图,在 Access 中链接该视图并尝试更新其中的记录。
  • @Gord 使用新安装的 SQL Server 2016 安装的SQL Server Native Client RDA 11.0.
  • 闻起来像数据问题,更具体地说是您的日期列中的无效数据。也许您可以运行查询来搜索任何无效的日期值。
  • @Rene datetime2 和 DateTime 之间的元数据映射无效 - 特别是在 Access 中无法实现默认精度,并且将列合并到键中时不会显示警告。

标签: ms-access sql-server-2016 temporal-database


【解决方案1】:

datetime2(7) 列中的默认精度超过了 Access 中可用的精度。当精度降低到datetime2(3) 时,查询变为可更新的。

即使这也可能太高了,因为小数秒可能只有 2 位多一点。链接表时,没有提示有效表示不足以表示列的消息。

SQL Server Profiler 的以下更新演示了有效时间字段值中的问题

exec sp_executesql N'UPDATE "dbo"."Product" 
    SET "Product status"=@P1  
    WHERE "Product line" = @P2 AND "Product" = @P3 AND 
        "Name" = @P4 AND "Product status" = @P5 AND "SysStartTime" = @P6 AND 
        "SysEndTime" = @P7',
    N'@P1 uniqueidentifier,@P2 uniqueidentifier,@P3 uniqueidentifier,@P4 nvarchar(50),@P5 uniqueidentifier,@P6 datetime2,@P7 datetime2',
    '3C...1E4B','38...2883','8E...0387',N'A300','44...6B76','2016-08-09 21:43:07.8710000','2016-08-09 22:45:59.1340000'

下面显示了更新前行的值 - 由于 Access 列的精度不足,更新失败。

Product line Product   Name Product status SysStartTime                SysEndTime
38...2883    8E...0387 A300 44...6B76      2016-08-09 21:43:07.8709730 2016-08-09 22:45:59.1342223

这与Rows showing as #DELETED 中BIGINT 列的范围问题有关。对较新的 SQL Server 类型进行全面映射会很有帮助。

部分 GUID 已被省略,以使输出更具可读性。

【讨论】:

  • 这个生成的 UPDATE sql 很奇怪,将所有列都放在了 WHERE 子句中。打开链接表的表设计时Access能识别主键吗?
  • @Andre 是的,正确检测到主键。更新看起来像 "#Deleted" errors with linked ODBC tables 后备尝试验证更新的正确性。
猜你喜欢
  • 2016-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多