Meilleur auteur de réponses
Auto_increment SQL Azure

Question
-
Bonjour à tous,
j'ai une table dans une bdd SqlAzure avec un champ cle qui est défini en temps que cle primaire et qui est identité.
De manière générale tout se passe bien avec un auto_increment de 1 en 1 lors de l'insert de données mais parfois, le compteur s'embrouille.
J'ai refait un truncate table récemment pour être sur de ne pas avoir malencontreusement supprimer de ligne et voici le valeurs de mes cles :
De 1 à 204, tout va bien, cle de 1 en 1 puis saut à
549, increment de 1 en 1 jusqu'à 553 puis
44891
147182
169625.
Comment se fais-ce que le compteur s'emballe comme cela?
Si quelequ'un à une idée, je suis preneur!
Merci d'avance
Réponses
-
Bonjour,
Il est difficile à dire si c’est le compteur qui s’emballe ou si quelqu’un a utilisé la syntaxe SET IDENTITY_INSERT (disponible aussi sur SQL Azure) pour changer le compteur de la colonne identité. Je crois que c’est la deuxième piste.
Cordialement,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.
- Marqué comme réponse Ciprian Duduiala mardi 21 juin 2011 06:06
Toutes les réponses
-
Bonjour,
Il est difficile à dire si c’est le compteur qui s’emballe ou si quelqu’un a utilisé la syntaxe SET IDENTITY_INSERT (disponible aussi sur SQL Azure) pour changer le compteur de la colonne identité. Je crois que c’est la deuxième piste.
Cordialement,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.
- Marqué comme réponse Ciprian Duduiala mardi 21 juin 2011 06:06
-
Il y a aussi la piste du ROLLBACK (explicite ou implicite). Si vous faites beaucoup d'INSERTs et ils echouent (par example il y a une violation d'une CHECK CONSTRAINT), il y aura surement un trou dans votre sequence. En effet, l'ID est associe au debut d'une transaction; pas a la fin.
Par example, essayez ceci:
CREATE TABLE TT (ID int IDENTITY(1,1) , loginid nvarchar(10) CONSTRAINT UQ_LOGINID UNIQUE (loginid)) INSERT INTO TT VALUES ('herve') INSERT INTO TT VALUES ('john') INSERT INTO TT VALUES ('herve') INSERT INTO TT VALUES ('john') INSERT INTO TT VALUES ('marie') GO SELECT * FROM TT
Vous verez que votre sequence sera 1,2,5.
Herve Roggero, Blue Syntax MVP SQL Azure Co-Author: Pro SQL Azure -
Je fais effectivement un check constraint à l'insert car je génére un Id aléatoire qui doit être unique. Il serait donc possible que, parfois, je retombe sur le même id est que cela me saute une cle.
Cela dit, je trouve bizarre que cela me fasse des sauts de plusieurs milliers de cle ( je passe de 553 à 44891, il serait quand même très improbable que je tombe 40000 fois de suite sur le même Id généré).
Sinon, je n'utilise pas de SET IDENTITY INSERT sur cette table.
Si quelqu'un a des pistes...
Merci d'avance!
-
Donc si je comprends bien, vous avez un CHECK CONSTRAINT sur un champs, qui genere un ID aleatoire et unique, en plus de votre UNIQUE ID. Pouvez-vous partager le contenu de votre contrainte? Comment generez-vous la cle de facon aleatoire?
Oui, ca parrait bizarre, je l'admet. Cependant, je vous conseille de continuer un peu plus sur la piste du CHECK CONSTRAINT tant que vous ne l'avez pas totalement prouve son innocence. Vous pouvez:
- deactiver le CHECK CONSTRAINT
- retirer le CHECK CONSTRAINT completement
Si vouz retirez la contrainte, vous avez toujours les "trous" dans votre unique id?
Finalement, avez-vous un job qui essaye d'ajouter des enregistrements, la nuit par example, sous forme de batch? Un Job qui ne reussi pas et fait un ROLLBACK va aussi creer un trou dans votre unique id.
Herve Roggero, MVP SQL Azure Co-Author: Pro SQL Azure http://www.herveroggero.com -
Bonjour,
d'abord merci pour l'interêt que vous portez à mon problème.
Ma table contient effectivement un champ ID(primary key, auto-increment) et un champ IDSESSION(string) avec une contrainte UNIQUE.
Je génère l'IDSESSION par programation avant l'insert (il s'agit d'une chaine de caractere aléatoire). Cet IdSession est généré lorsqu'un utilisateur se connecte à l'application Web et il me permet à chaque appel d'un service Wcf de vérifier que cet utilisateur soit bien authentifié.
Pour être sur de ne pas retomber 2 fois sur le même IdSession, a l'insert dans la table, la contrainte me renvoie une erreur Sql au cas ou je sois retombé par hasard sur un idsession existant. Dans ce cas, je regénère l'IdSession et retente l'insert jusqu'à ne plus avoir l'erreur de violation de contrainte.
Je n'ai aucun autre programme qui effectue des insert dans cette table.
Voici le script de création de ma table généré par Sql server management studio
Peut-être est-ce un hasard, mais tous les sauts ont eu lieu entre le 13 et le 15 juin; depuis, plus de trou. Il est donc difficile de tester en supprimant la contrainte car cela fonctionne dans 99% des cas.CREATE TABLE [dbo].[Session]( [cleclient] [int] NOT NULL, [IdSession] [varchar](50) NOT NULL, [datecrea] [datetime] NULL, [Ip] [varchar](50) NULL, [datemaj] [datetime] NULL, [cleclient_final] [int] NULL, [cle] [int] IDENTITY(1,1) NOT NULL, CONSTRAINT [PrimaryKey_0c43d47d-0525-4a2d-af3c-4c648239e014] PRIMARY KEY CLUSTERED ( [cle] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON), UNIQUE NONCLUSTERED ( [IdSession] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) )
Peut-être ma contrainte est-elle mal créer dans Sql Server?
Merci d'avance pour vos réponse
-
Bonjour, et merci des details supplementaires.
Je realise maintenant que votre champ IdSession est genere par votre code, non par SQL.
Pouvez-vous changer votre code pour qu'il genere un GUID, plutot que de calculer une valeur unique vous-meme? Ce serait la solution la plus simple, si effectivement cette routine est a l'origine du probleme.
Sinon, vous pouvez changer votre facon d'inserer votre enregistrement sans dependre de votre contrainte unique. Par example vous pouvez creer un INSTEAD OF TRIGGER. Comme le INSTEAD OF prend la place du INSERT vous pouvez verifier la valeur de SessionId juste avant, et "cacher" le probleme. Le probleme de base cependant ne sera pas elimine.
CREATE TRIGGER InsteadInst on [session] INSTEAD OF INSERT AS BEGIN IF (NOT Exists(SELECT * FROM [session] WHERE idsession = (SELECT idsession FROM inserted))) INSERT INTO [session] (cleclient, idsession, datecreat, ip, datemaj, cleclient_final) SELECT cleclient, idsession, datecreat, ip, datemaj, cleclient_final from inserted END
Je suis curieux de connaitre le resultat... :)
Herve Roggero, MVP SQL Azure Co-Author: Pro SQL Azure http://www.herveroggero.com