TL:DR; version:
If I insert a record into a linked table that has a trigger that inserts a record in a different table, Access displays the global i
In the end, I've tried numerous workarounds to solve this problem. For anyone encountering it in the future, here are some of the working ones, and my considerations.
At first, I just moved data entry to a form, and added the following code:
Private Sub Form_AfterInsert()
Me.Requery
End Sub
While working, this had numerous disadvantages.
Then, I just incremented the identity seed of my _Changes table to beyond that of the normal table:
DBCC CHECKIDENT ('MyTable_Changes', RESEED, 10000);
This avoids @@IDENTITY existing in MyTable, so the wrong data will no longer be displayed after adding a row. This works, but Access will no longer fetch defaults for blank columns after adding. However, for others, this might not be relevant and might be the simplest solution.
I also tried changing the identity column to a GUID
CREATE TABLE MyTable_Changes(
[ID] [int] NOT NULL,
[Col1] [nvarchar](255) NULL,
[Col2] [nvarchar](255) NULL,
[IDChange] uniqueidentifier ROWGUIDCOL PRIMARY KEY NOT NULL
CONSTRAINT [DF_MyTable_Changes_IDChange] DEFAULT newsequentialid()
)
This worked (since @@IDENTITY no longer got changed), fetching defaults worked, it added some complexity (I was inserting into two tables joined by a one-many relationship and had to use the OUTPUT clause to fetch the ID on one of them), and my boss decided GUIDs were unintuitive and shouldn't be used.
In the end, Gord Thompson's answer was the one I went with. I modified the code to use a table variable instead of a temporary table to make the scope of the table more explicit.
CREATE TRIGGER MyTableTrigger ON MyTable AFTER Insert, Update
AS
BEGIN
SET NOCOUNT ON;
-- Capture @@identity
DECLARE @identity int;
SET @identity=@@identity;
-- Inserts here
INSERT INTO MyTable_Changes(ID, Col1, Col2)
SELECT * FROM Inserted;
-- reset @@identity
DECLARE @strsql varchar(255)
SET @strsql='
DECLARE @t Table(id INTEGER IDENTITY(' + cast(@identity as varchar(10)) + ',1) PRIMARY KEY);
INSERT INTO @t DEFAULT VALUES;
'
EXEC(@strsql);
END