none
Auto_increment SQL Azure RRS feed

  • 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

    mercredi 15 juin 2011 10:36

Réponses

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


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    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.

    vendredi 17 juin 2011 13:24
  • 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
    mardi 21 juin 2011 17:55
  • 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!

    lundi 27 juin 2011 10:29
  • 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
    lundi 27 juin 2011 20:45
  • 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

    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 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.

    Peut-être ma contrainte est-elle mal créer dans Sql Server?

    Merci d'avance pour vos réponse

    jeudi 30 juin 2011 13:52
  • 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
    jeudi 30 juin 2011 14:52