In einer meiner Tabellen Fee
in der Spalte "ReceiptNo" in SQL Server 2012 sprang das Identitätsinkrement der Datenbank plötzlich auf 100 statt auf 1, abhängig von den folgenden zwei Dingen.
Wenn es 1205446 ist, springt es zu 1206306, wenn es 1206321 ist, springt es zu 1207306 und wenn es 1207314 ist, springt es zu 1208306. Ich möchte Sie darauf hinweisen, dass die letzten drei Ziffern konstant bleiben, dh 306, wenn das Springen erfolgt tritt wie im folgenden Bild gezeigt auf.
Dieses Problem tritt auf, wenn ich meinen Computer neu starte
order by ReceiptNo
Ihrer Abfrage hinzufügen , sind diese Datensätze wirklich nicht vorhanden? Sind Sie sicher, dass beim Einfügen von Datensätzen keine Fehler vorliegen? Wenn ein Datensatz versucht, eingefügt zu werden, und dies fehlschlägt, wird die Identität erhöht. Dies gilt auch, wenn Datensätze gelöscht werden. Wenn Datensätze gelöscht werden, wird derReceiptNo
nicht zurückgesetzt. Können Sie die Erstellungs-Tabelle für dieFee
Tabelle veröffentlichen?1206306
,1207306
,1207806
) bedeutet , dass die Erklärung in dem Connect - Artikel Thema Sicherheit grenzender Wahrscheinlichkeit gilt.Antworten:
Dieses Verhalten tritt aufgrund einer Leistungsverbesserung seit SQL Server 2012 auf.
Standardmäßig wird jetzt eine Cache-Größe von 1.000 verwendet, wenn beim Zuweisen von
IDENTITY
Werten für eineint
Spalte und beim Neustart des Dienstes nicht verwendete Werte "verloren" gehen (die Cache-Größe beträgt 10.000 fürbigint
/numeric
).Dies wird in der Dokumentation erwähnt
Aus den von Ihnen angezeigten Daten geht hervor, dass dies nach der Dateneingabe für den 22. Dezember geschehen ist. Beim Neustart von SQL Server wurden die Werte reserviert
1206306 - 1207305
. Nach der Dateneingabe für den 24. bis 25. Dezember wurde ein weiterer Neustart durchgeführt und SQL Server reservierte den nächsten1207306 - 1208305
in den Einträgen sichtbaren Bereich für den 28. Dezember .Sofern Sie den Dienst nicht mit ungewöhnlicher Häufigkeit neu starten, ist es unwahrscheinlich, dass "verlorene" Werte den vom Datentyp zugelassenen Wertebereich erheblich beeinträchtigen. Daher ist es am besten, sich darüber keine Sorgen zu machen.
Wenn dies aus irgendeinem Grund ein echtes Problem für Sie ist, sind einige mögliche Problemumgehungen ...
SEQUENCE
anstelle einer Identitätsspalte verwenden und beispielsweise eine kleinere Cache-Größe definieren undNEXT VALUE FOR
in einer Spalten-Standardeinstellung verwenden.IDENTITY
Zuordnung wie in Versionen bis 2008 R2 protokolliert wird. Dies gilt global für alle Datenbanken.ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF
um das Identitäts-Caching für eine bestimmte Datenbank zu deaktivieren.Sie sollten sich bewusst sein, dass keine dieser Problemumgehungen keine Lücken gewährleistet. Dies wurde nie garantiert,
IDENTITY
da dies nur durch Serialisierung von Einfügungen in die Tabelle möglich wäre. Wenn Sie eine lückenlose Säule benötigen, müssen Sie eine andere Lösung als entwederIDENTITY
oder verwendenSEQUENCE
quelle
SEQUENCE
anstelle von a verwendenIDENTITY
und die Sequenz auf eine Cache-Größe von festlegen0
.CREATE TABLE
ich sehe , Sie verwendennumeric(7)
und haben die Abzählen an begann1200001
das bedeutet , Sie würden auslaufen nach8,799
Tagen (24 Jahre) , wenn Sie 1.000 pro Tag.big int
"springt" eine Spalte normalerweise pro Neustart um 10.000.Dieses Problem tritt nach dem Neustart des SQL Servers auf.
Die Lösung ist:
Führen Sie SQL Server Configuration Manager aus .
Wählen Sie SQL Server Services .
Klicken Sie mit der rechten Maustaste auf SQL Server und wählen Sie Eigenschaften .
In dem sich öffnenden Fenster unter Startparameter , Typ
-T272
und klicken Sie auf Hinzufügen , und drücken Sie Apply - Taste und neu starten.quelle
Von können
SQL Server 2017+
Sie ALTER DATABASE SCOPED CONFIGURATION verwenden :quelle
Ich weiß, dass meine Antwort zu spät zur Party kommen könnte. Aber ich habe auf eine andere Weise gelöst, indem ich eine gespeicherte Startprozedur in SQL Server 2012 hinzugefügt habe.
Erstellen Sie eine folgende gespeicherte Prozedur in der Master-DB.
Fügen Sie es dann zu Start hinzu, indem Sie die folgende Syntax verwenden.
Dies ist eine gute Idee, wenn Sie nur wenige Tabellen haben. Wenn Sie jedoch für viele Tabellen arbeiten müssen, funktioniert diese Methode immer noch, ist aber keine gute Idee.
quelle
Dies ist immer noch ein sehr häufiges Problem bei vielen Entwicklern und Anwendungen, unabhängig von ihrer Größe.
Leider beheben die obigen Vorschläge nicht alle Szenarien, dh Shared Hosting. Sie können sich nicht darauf verlassen, dass Ihr Host den Startparameter -t272 festlegt.
Wenn Sie über vorhandene Tabellen verfügen, die diese Identitätsspalten für Primärschlüssel verwenden, ist es ein RIESIGER Aufwand, diese Spalten zu löschen und neue zu erstellen, um die BS-Sequenzumgehung zu verwenden. Die Sequenzumgehung ist nur dann gut, wenn Sie die Tabellen in SQL 2012+ von Grund auf neu entwerfen
Fazit: Wenn Sie sich auf SQL Server 2008R2 befinden, bleiben Sie auf IT. Im Ernst, bleib dran. Bis Microsoft zugibt, dass sie einen RIESIGEN Fehler eingeführt haben, der auch in SQL Server 2016 noch vorhanden ist, sollten wir erst dann ein Upgrade durchführen, wenn sie ihn besitzen und die IT reparieren.
Microsoft hat sofort eine grundlegende Änderung eingeführt, dh, sie haben eine funktionierende API beschädigt, die nicht mehr wie geplant funktioniert, da ihr System bei einem Neustart ihre aktuelle Identität vergisst. Cache oder kein Cache, dies ist inakzeptabel, und der Microsoft-Entwickler namens Bryan muss ihn besitzen, anstatt der Welt mitzuteilen, dass er "beabsichtigt" und eine "Funktion" ist. Sicher, das Caching ist eine Funktion, aber den Überblick über die nächste Identität zu verlieren, ist keine Funktion. Es ist ein verdammter Käfer !!!
Ich werde die von mir verwendete Problemumgehung freigeben, da sich meine Datenbanken auf Shared Hosting-Servern befinden. Außerdem lösche ich meine Primärschlüsselspalten nicht und erstelle sie neu. Dies wäre eine riesige PITA.
Stattdessen ist dies mein beschämender Hack (aber nicht so beschämend wie dieser POS-Fehler, den Microsoft eingeführt hat).
Hack / Fix:
Setzen Sie vor Ihren Einfügebefehlen vor jeder Einfügung Ihre Identität neu ein. Dieser Fix wird nur empfohlen, wenn Sie keine Administratorsteuerung über Ihre SQL Server-Instanz haben. Andernfalls empfehle ich, beim Neustart des Servers erneut zu säen.
Nur diese 3 Zeilen unmittelbar vor dem Einfügen, und Sie sollten bereit sein zu gehen. Es wird die Leistung wirklich nicht so stark beeinträchtigen, dh es wird nicht bemerkt.
Viel Glück.
quelle
Es gibt viele mögliche Gründe, um Identitätswerte zu überspringen. Sie reichen von Rollback-Einfügungen bis hin zum Identitätsmanagement für die Replikation. Was dies in Ihrem Fall verursacht, kann ich nicht sagen, ohne einige Zeit in Ihrem System zu verbringen.
Sie sollten jedoch wissen, dass Sie in keinem Fall davon ausgehen können, dass eine Identitätsspalte Contiguos ist. Es gibt einfach zu viele Dinge, die Lücken verursachen können.
Weitere Informationen hierzu finden Sie hier: http://sqlity.net/de/792/the-gap-in-the-identity-value-sequence/
quelle