it-swarm.com.de

Inkrement der SQL Server 2012-Spaltenidentität springt beim 7. Eintrag von 6 auf 1000+

Ich habe ein seltsames Szenario, in dem die Spalte "auto identity int" in meiner SQL Server 2012-Datenbank nicht ordnungsgemäß inkrementiert wird.

Angenommen, ich habe eine Tabelle, die eine int auto-Identität als Primärschlüssel verwendet und sporadisch Inkremente überspringt, zum Beispiel:

1, 2, 3, 4, 5, 1004, 1005

Dies geschieht auf einer zufälligen Anzahl von Tabellen zu sehr zufälligen Zeiten, kann es nicht replizieren, um Trends zu finden.

Wie ist das passiert? Gibt es eine Möglichkeit, damit aufzuhören?

121
Andy Clark

Das ist alles völlig normal. Microsoft hat in SQL Server 2012 sequences hinzugefügt. Schließlich kann es sein, dass ich die Art und Weise, wie Identitätsschlüssel generiert werden, hinzufüge und ändere. Schauen Sie sich hier für eine Erklärung an.

Wenn Sie das alte Verhalten haben möchten, können Sie:

  1. verwenden Sie das Ablaufverfolgungsflag 272. Dadurch wird für jeden generierten Identitätswert ein Protokollsatz generiert. Die Leistung der Identitätsgenerierung kann durch Aktivieren dieses Ablaufverfolgungsflags beeinträchtigt werden.
  2. verwenden Sie einen Sequenzgenerator mit der Einstellung NO CACHE ( http://msdn.Microsoft.com/en-us/library/ff878091.aspx )
75
Mithrandir

Habe das gleiche Problem, habe den folgenden Fehlerbericht in SQL Server 2012 gefunden. Wenn immer noch relevant, siehe Bedingungen, die das Problem verursachen - es gibt auch einige Problemumgehungen (habe es aber nicht versucht). Failover oder Neustart führt zu erneuter Identität

4
yoosha

Während das Ablaufverfolgungsflag 272 für viele funktionieren kann, funktioniert es definitiv nicht für gehostete SQL Server Express-Installationen. Also habe ich eine Identitätstabelle erstellt und diese über einen INSTEAD OF-Trigger verwendet. Ich hoffe, dass dies jemand anderem hilft und/oder anderen die Möglichkeit gibt, meine Lösung zu verbessern. In der letzten Zeile wird die zuletzt hinzugefügte Identitätsspalte zurückgegeben. Da ich dies normalerweise zum Hinzufügen einer einzelnen Zeile verwende, gibt dies die Identität einer einzelnen eingefügten Zeile zurück.

Die Identitätstabelle:

CREATE TABLE [dbo].[tblsysIdentities](
[intTableId] [int] NOT NULL,
[intIdentityLast] [int] NOT NULL,
[strTable] [varchar](100) NOT NULL,
[tsConcurrency] [timestamp] NULL,
CONSTRAINT [PK_tblsysIdentities] PRIMARY KEY CLUSTERED 
(
    [intTableId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,  ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

und der Insert-Trigger:

-- INSERT --
IF OBJECT_ID ('dbo.trgtblsysTrackerMessagesIdentity', 'TR') IS NOT NULL
   DROP TRIGGER dbo.trgtblsysTrackerMessagesIdentity;
GO
CREATE TRIGGER trgtblsysTrackerMessagesIdentity
ON dbo.tblsysTrackerMessages
INSTEAD OF INSERT AS 
BEGIN
    DECLARE @intTrackerMessageId INT
    DECLARE @intRowCount INT

    SET @intRowCount = (SELECT COUNT(*) FROM INSERTED)

    SET @intTrackerMessageId = (SELECT intIdentityLast FROM tblsysIdentities WHERE intTableId=1)
    UPDATE tblsysIdentities SET intIdentityLast = @intTrackerMessageId + @intRowCount WHERE intTableId=1

    INSERT INTO tblsysTrackerMessages( 
    [intTrackerMessageId],
    [intTrackerId],
    [strMessage],
    [intTrackerMessageTypeId],
    [datCreated],
    [strCreatedBy])
    SELECT @intTrackerMessageId + ROW_NUMBER() OVER (ORDER BY [datCreated]) AS [intTrackerMessageId], 
    [intTrackerId],
   [strMessage],
   [intTrackerMessageTypeId],
   [datCreated],
   [strCreatedBy] FROM INSERTED;

   SELECT TOP 1 @intTrackerMessageId + @intRowCount FROM INSERTED;
END