IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Assurer un numéro de séquence sans trou


Sujet :

Développement SQL Server

  1. #1
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut Assurer un numéro de séquence sans trou
    Hello,

    Au hasard du net, je suis tombé sur un code qui m'a l'air plutôt élégant pour s'assurer d'avoir une suite continue de numéro sans devoir s'emmerder à gérer les trous et sans devoir passer le niveau d'isolation des transactions sur serializable.

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    while 1=1
        begin        
        declare @new_nr int
        select  @new_nr = max(InvoiceNr) + 1
        from    dbo.Invoices
     
        if @new_nr is null
            set @new_nr = 1
     
        insert  dbo.Invoices
                (InvoiceNr, ...)
        values  (@new_nr, ...)
     
        if @@rowcount = 1
            break
        end
    Où Invoices serait une table dans ce goût-là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE [Imports].[Invoices_Numbers]
      (
         [InvoiceNumber] [INT] IDENTITY(1, 1) NOT NULL
         ,[Deleted]      [BIT] NOT NULL
         ,[Used]         [BIT] NOT NULL,
         CONSTRAINT [PK_Invoices_Numbers] PRIMARY KEY CLUSTERED ( [InvoiceNumber] ASC ) 
      )
    ON [PRIMARY]
    Qu'en pensez-vous ?
    Kropernic

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    1/ Que ça gère justement pas les trous
    2/ Qu'à ce compte là, autant utiliser une séquence, qui sera bien plus véloce et bien plus fiable

    Car là, si on insère en lot des données en utilisant ton code, on va avoir toutes les lignes avec le même numéro ! (quoique non, en fait ça doit juste planter )

    A la limite, faut modifier la première requête en :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select min(nr) + 1
    from invoices_numbers i1
    left outer join invoices_numbers i2 on i2.nr = i1.nr + 1
    where i2.nr is null

    => Au moins, ça bouchera les trous !
    On ne jouit bien que de ce qu’on partage.

  3. #3
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Pour la séquence, j'ai oublié de dire que je suis encore (à mon plus grand désespoir) avec 2008R2.

    Sinon, c'est vrai aussi que je n'ai pas préciser le contexte... (c'est ma faute... tellement plongé dedans depuis quelques jours que j'oublie les choses essentielles pour les personnes extérieures)

    Je vais prochainement devoir réécrire un programme de création de facture. A cette fin, il me faut un moyen d'avoir une suite de numéro sans trou. Donc identity(x,1), c'est mort car si un insert se passe mal, ça bouffe un numéro.

    Du coup, j'suis tombé là-dessus.

    Et y aura jamais d'insertion multiple vu que ça viendra d'une application et que les gens au customer's desk bin il s'occupe d'un client à la fois chacun ^^.
    Kropernic

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 772
    Points : 52 735
    Points
    52 735
    Billets dans le blog
    5
    Par défaut
    Mais vous avez le droit de faire des erreurs ! Il faut juste ne pas annuler la transaction, mais insérer le numéro de facture avec marqué ANNULÉE suite à erreur de saisie !
    Si vous faisiez les choses sur un facturier manuel... vous n'auriez jamais droit à l'erreur sous peine de mort ?????
    La numérotation incrémentale continue sert uniquement à vérifier ou sont partit vos factures afin de ne pas en avoir 2 qui portent le même n°. Mais une destination possible est la poubelle !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Bin oui, je sais bien qu'on a le droit de faire des erreurs. C'est humain.

    Seulement ça veut dire que je dois donc prévoir un mécanisme pour pouvoir dire que tel numéro est manquant à cause de telle ou telle erreur.
    Ca c'est pour mon point de vue.

    Pour le point de vue de la hiérarchie, un programme ne doit pas faire d'erreur. Donc pas de trou dans la numérotation ^^.

    Sinon, ce je voulais être sûr à 100% (quand moi je regarde ça m'a l'air ok mais je me donne un taux de validation de 90%), c'est que la boucle while proposer est bien valide pour les insertions ligne à ligne et fait bien ce qu'elle est sensée faire.
    Kropernic

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 772
    Points : 52 735
    Points
    52 735
    Billets dans le blog
    5
    Par défaut
    Aucun système informatique, programme ou autre n'est capable de vous assurer qu'il ne fera jamais d'erreur. C'est un non sens absolu. Se baser sur une telle affirmation estb proprement stupide et va engendrer des problématoques bien pires.
    la solution consiste tout simplement à ajouter à votre table une vue qui "récupère" les "trous" et affiche que la facture a été supprimée du fait d'une erreur de saisie.

    A lire aussi : http://www.xirius.be/upload/chroniqu...bre%202011.pdf

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. Séquence sans trou
    Par r83 dans le forum SQL
    Réponses: 6
    Dernier message: 18/02/2013, 15h02
  2. Réponses: 1
    Dernier message: 14/01/2008, 15h45
  3. Récupérer un numéro de séquence
    Par R1pToR dans le forum Struts 1
    Réponses: 22
    Dernier message: 17/07/2007, 17h14
  4. [9i] séquence sans trou
    Par sygale dans le forum Oracle
    Réponses: 2
    Dernier message: 11/04/2007, 13h25
  5. [débutant] "auto_increment" sans trou ?
    Par Mathusalem dans le forum Oracle
    Réponses: 6
    Dernier message: 24/04/2006, 16h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo