在SQL服务器上附加到链接表时,阻止Access使用错误的标识

Eri*_*k A 5 sql database sql-server ms-access triggers

TL:DR; 版:

如果我将记录插入到具有在不同表中插入记录的触发器的链接表中,Access将显示全局标识(该不同表的标识)而不是正确的主键,并使用以下值填充列:如果存在具有相应标识的记录,则具有相应标识的记录.

有没有办法停止/解决这种行为?

MCVE:

我有下表:

CREATE TABLE MyTable(
    [ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Col1] [nvarchar](255) NULL,
    [Col2] [nvarchar](255) NULL
)
Run Code Online (Sandbox Code Playgroud)

该表附有以下信息(在创建触发器之前)

INSERT INTO [MyTable]
           ([Col1]
           ,[Col2])
     VALUES
           ('Col1'
           ,'Col2')
GO 10
Run Code Online (Sandbox Code Playgroud)

以下表记录了更改:

CREATE TABLE MyTable_Changes(
    [ID] [int] NOT NULL,
    [Col1] [nvarchar](255) NULL,
    [Col2] [nvarchar](255) NULL,
    [IDChange] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY
)
Run Code Online (Sandbox Code Playgroud)

此表附加了以下触发器:

CREATE TRIGGER MyTableTrigger ON MyTable AFTER Insert, Update
    AS
BEGIN 
    SET NOCOUNT ON;
    INSERT INTO MyTable_Changes(ID, Col1, Col2)
    SELECT * FROM Inserted
END
Run Code Online (Sandbox Code Playgroud)

MyTable是Microsoft Access中的链接表,使用以下ODBC连接字符串:

 ODBC;DRIVER=SQL Server;SERVER=my\server;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=MyDB;
Run Code Online (Sandbox Code Playgroud)

我正在使用Access 2010和.accdb文件

问题:

我正在通过GUI插入记录.我在启用触发器之前插入了几条记录,MyTable的标识种子为100,但对于MyTable_Changes,标识种子为10.

当我向MyTable添加新记录,并且我将Col1设置为"A"时,插入后,插入记录的ID列显示为11,Col2显示为ID11的Col2值.Col1正常显示.点击F5后,记录显示就像我刚添加它一样.

我尝试过的:

我读了很多帖子(比如这个).我已经尝试了一个紧凑的修复,在Access中更改表上的种子(由于它是一个链接表,它不起作用),但是无法解决它.

现在,我已经包含了一个解决方案,它可以打开链接表作为数据表格式并在更新后重新查询,然后导航到最后一条记录,但这远非最佳,因为它增加了添加记录所需的时间,并且人们无法使用navpane打开表格并添加记录.

图片:(左:添加记录前,右:后) 在此输入图像描述

请注意,更新后Col1和Col2都更改为与ID 1对应的值.刷新后,我添加的记录(ID 11,Col1 a,Col2 Null)正确显示.

Gor*_*son 5

ODBC跟踪显示Access 在将行插入SQL Server链接表后确实正在调用SELECT @@IDENTITY(而不是SCOPE_IDENTITY()):

Database1       e00-1490    EXIT  SQLExecDirectW  with return code 0 (SQL_SUCCESS)
        HSTMT               0x00000000004D6990
        WCHAR *             0x000000000F314F28 [      -3] "INSERT INTO  "dbo"."Table1"  ("txt") VALUES (?)\ 0"
        SDWORD                    -3

...

Database1       e00-1490    EXIT  SQLExecDirectW  with return code 0 (SQL_SUCCESS)
        HSTMT               0x00000000004D6990
        WCHAR *             0x000007FED7E6EE58 [      -3] "SELECT @@IDENTITY\ 0"
        SDWORD                    -3
Run Code Online (Sandbox Code Playgroud)

此外,此行为似乎取决于正在使用的ODBC驱动程序,因为使用MySQL Connector/ODBC的类似测试显示Access LAST_INSERT_ID()在将行插入MySQL链接表后不会调用相应的MySQL函数.

鉴于Access正在调用SELECT @@IDENTITY,我们必须按如下方式修改触发器(source:here)以将@@ IDENTITY值重置为其原始值

create trigger mytable_insert_trigger on mytable for insert as

declare @identity int
declare @strsql varchar(128)

set @identity=@@identity
--your code
--insert into second table ...
--your code
set @strsql='select identity (int, ' + cast(@identity as varchar(10)) + ',1) as id into #tmp'
execute (@strsql)
Run Code Online (Sandbox Code Playgroud)