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

SQL Oracle Discussion :

Problème avec sequence sous 11g


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Enseignant-chercheur
    Inscrit en
    Octobre 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant-chercheur

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2
    Par défaut Problème avec sequence sous 11g
    Bonjour,
    Lorsque j'exécute le script suivant (tout bête !), j'obtiens comme chiffre pour mes n° de membre 2 et 3, alors que je devrais obtenir 1 puis 2. J'ai ce problème sous 11g et 11gR2, mais par contre, cela fonctionnait très bien sous 10g. Quelqu'un a-t-il une idée ?
    Merci.

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    drop table MEMBRE cascade constraints;
     
    /*==============================================================*/
    /* Table : MEMBRE                                               */
    /*==============================================================*/
    create table MEMBRE 
    (
       NUM_MEMBRE           NUMBER(6)            not null,
       NOM                  VARCHAR2(80)         not null,
       PRENOM               VARCHAR2(80)         not null,
       RUE                  VARCHAR2(100)        not null,
       CP                   CHAR(5)              not null,
       VILLE                VARCHAR2(50)         not null,
       TELEPHONE            CHAR(10),
       ADHESION             DATE                 not null,
       DUREE                NUMBER(2)            not null,
       constraint PK_MEMBRE primary key (NUM_MEMBRE),
       constraint CK_MEMBRES_DUREE check (DUREE>0)
    );
     
    drop sequence MEMBRE_SEQ;
    Create sequence MEMBRE_SEQ;
     
    Insert into MEMBRE (NUM_MEMBRE, NOM, PRENOM, RUE, CP, VILLE, TELEPHONE, ADHESION, DUREE) values (MEMBRE_SEQ.nextval, 'ALBERT', 'Marc', '13 rue des alpes', '69008', 'Lyon', '0601020304', sysdate-60, 1);
    Insert into MEMBRE (NUM_MEMBRE, NOM, PRENOM, RUE, CP, VILLE, TELEPHONE, ADHESION, DUREE) values (MEMBRE_SEQ.nextval, 'BERNAUDET', 'Barnabé', '6 rue des bécasses', '69007', 'Lyon', '0602030105', sysdate-10, 3);
    COMMIT;
     
    select * from membre;

  2. #2
    Membre très actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2011
    Messages : 146
    Par défaut
    Bonjour,

    http://download.oracle.com/docs/cd/B...ments_6015.htm

    Quand tu créés une séquence la première valeur par défaut est 1.

    Dans ton premier insert on a soit 2.

  3. #3
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Par défaut
    En effet, c'est un problème réel et répertorié, effet secondaire désagréable de la création de segment différée. Ce mécanisme permet de créer une table sans allouer d'espace (c'est à dire sans créer de segment) tant qu'on n'insère pas au moins une ligne.

    Ce problème troublant survient lorsque les conditions suivantes sont cumulées :
    - Oracle 11gR2
    - édition Entreprise
    - deferred_segment_creation=true
    - table vide
    - séquence non initialisée (encore jamais appelée)
    - schéma autre que SYS ou SYSTEM

    Dans ces conditions, lorsque vous insérez la première ligne de la table tout en faisant appel à une séquence "toute neuve", celle-ci subit une double incrémentation.

    A la ligne 39 de cet exemple, on voit que la séquence, appelée pour la première fois, renvoie 2 au lieu de 1.
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    SYSTEM@ORA112>show parameter defer
     
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    deferred_segment_creation            boolean     TRUE
     
    SYSTEM@ORA112>drop table scott.test purge;
     
    Table supprimée.
     
    SYSTEM@ORA112>drop sequence seqtest;
     
    Séquence supprimée.
     
    SYSTEM@ORA112>create sequence seqtest start with 1 increment by 1;
     
    Séquence créée.
     
    SYSTEM@ORA112>create table scott.test(a int);
     
    Table créée.
     
    SYSTEM@ORA112>select segment_name, segment_type
      2  from dba_segments
      3  where owner='SCOTT'
      4  and segment_name='TEST';
     
    --> aucun segment n'est associé à cette table
    aucune ligne sélectionnée
     
    SYSTEM@ORA112>insert into SCOTT.test values(seqtest.nextval);
     
    1 ligne créée.
     
    SYSTEM@ORA112>select * from test;
     
             A
    ----------
             2
     
    SYSTEM@ORA112>select segment_name, segment_type
      2  from dba_segments
      3  where owner='SCOTT'
      4  and segment_name='TEST';
     
    --> il y a maintenant un segment
    SEGMENT_NAME                         SEGMENT_TYPE
    -------------------------------    ---------------
    TEST                                         TABLE
    La note Metalink 1050193.1 décrit ce phénomène, et a le culot de considérer que c'est un comportement normal (alors que c'était initialement considéré comme une bogue de sévérité 2), en arguant qu'une séquence n'a pas vocation à produire des numéros forcément prévisibles.

    Pour éviter tout souci, il faut désactiver la création de segment différée.

    Cela peut se faire au niveau de la table par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    create table test(a int)
    segment creation immediate;
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    SYSTEM@ORA112>show parameter defer
     
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    deferred_segment_creation            boolean     TRUE
     
    SYSTEM@ORA112>drop table scott.test purge;
     
    Table supprimée.
     
    SYSTEM@ORA112>drop sequence seqtest;
     
    Séquence supprimée.
     
    SYSTEM@ORA112>create sequence seqtest;
     
    Séquence créée.
     
    SYSTEM@ORA112>
    SYSTEM@ORA112>create table scott.test(a int)
      2  segment creation immediate;
     
    Table créée.
     
    SYSTEM@ORA112>select segment_name, segment_type
      2  from dba_segments
      3  where owner='SCOTT'
      4  and segment_name='TEST';
     
    SEGMENT_NAME            SEGMENT_TYPE
    ----------------------- ------------------
    TEST                    TABLE
     
    SYSTEM@ORA112>insert into SCOTT.test values(seqtest.nextval);
     
    1 ligne créée.
     
    SYSTEM@ORA112>select * from scott.test;
     
             A
    ----------
             1

  4. #4
    Membre extrêmement actif
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Billets dans le blog
    6
    Par défaut
    pourquoi ne pas créer cette sequence comme:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    create sequence MEMBRE_SEQ
    minvalue 1
    maxvalue 999999999999999999999999999
    start with 1
    increment by 1
    cache 20;

  5. #5
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    ...La note Metalink 1050193.1 décrit ce phénomène, et a le culot de considérer que c'est un comportement normal (alors que c'était initialement considéré comme une bogue de sévérité 2), en arguant qu'une séquence n'a pas vocation à produire des numéros forcément prévisibles.
    ...
    Personnellement, je partage en partie leur point de vue.

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    C'est vrai que le bug est surprenant et je n'irai pas dire que c'est un comportement normal, mais ce n'est pas plus grave qu'un "trou" créé suite à un rollback.

  7. #7
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Par défaut
    Citation Envoyé par Waldar Voir le message
    ...mais ce n'est pas plus grave qu'un "trou" créé suite à un rollback.
    Si c'est plus grave, car ça change le comportement qu'on connaissait jusque là. Une séquence est censée fournir des numéros à partir du START WITH, en respectant INCREMENT BY, et ce
    sans trou sous réserve qu'on ne fasse pas de ROLLBACK ou que l'instance ne soit pas redémarrée.

    Je connais plus d'un script d'initialisation d'environnement basé sur ces hypothèses. Si on a dit START WITH 1, ils s'attendent à trouver 1 comme première valeur.
    J'avais concrètement rencontré ce cas en début d'année dernière, où ce décalage initial de la séquence fichait en l'air la validité des clés étrangères.

    Alors bien sûr, on peut objecter que ces scripts étaient critiquables, mais le fait est que ce qui marchait avant ne marchait plus, et ce sans raison valable.

  8. #8
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Personnellement, je partage en partie leur point de vue.
    Sur ce coup-là, ils sont franchement de mauvaise foi chez Oracle.
    La création de segment différée provoque une petite régression qui leur avait échappé, ils feraient mieux de corriger leur code pour que les choses continuent à fonctionner comme avant, plutôt que de trouver un prétexte digne du pire des politiciens pour justifier cette anomalie.

    Une séquence n'a pas à fournir des valeurs prévisibles ?
    A quoi sert d'avoir une clause START WITH alors ?
    A quoi sert de préciser INCREMENT BY ?

    Oracle est déjà un produit assez compliqué comme ça avec ses exceptions de comportement dans tous les sens, sans avoir besoin d'en rajouter...

  9. #9
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Cher Pomalaix,
    Vous avez sans aucun doute raison. Mais, je pense également que l’utilisation correcte d’une séquence n’impose en rien la présence obligatoire d’une valeur bien précisée comme 1 dans ce cas. Donc ce n’est pas joli mais ce n’est pas grave non plus.
    De plus ça va faire une « bonne question d’expert » d’ici peu de temps :
    Le paramétrage de base est …
    Je crée une séquence comme suit …
    Je l’utilise comme suit …
    Quelle est la valeur insérée dans la table : 1 ou 2 ?

  10. #10
    Expert confirmé
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 822
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    Citation Envoyé par mnitu Voir le message
    Personnellement, je partage en partie leur point de vue.
    Pour en rajouter un peu, je dirais que l'erreur de départ, c'est d'avoir fait des sequences qui
    1) s'appellent sequences
    2) donnent un NUMBER
    On aurait un 'generator' qui donnerait seulement un RAW en garantissant seulement de ne pas tomber 2 fois sur le même, et personne ne se plaindrait des trous
    Codialement,
    Franck.

  11. #11
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Comme un sys_guid() ?

  12. #12
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par pachot Voir le message
    ...
    On aurait un 'generator' qui donnerait seulement un RAW en garantissant seulement de ne pas tomber 2 fois sur le même, et personne ne se plaindrait des trous
    Mais non c’est pire que ça : la machine s’en fout de trous c’est l’humain qu’en a besoin, en gros pour faire comme avant… !

Discussions similaires

  1. Problème avec un sous-sous formulaire
    Par arthur24 dans le forum Access
    Réponses: 2
    Dernier message: 13/01/2006, 16h50
  2. Problème avec EInOutError sous delphi 2005
    Par Teb dans le forum Langage
    Réponses: 3
    Dernier message: 19/08/2005, 11h48
  3. fichier .bat : problèmes avec des sous-répertoires
    Par aymron dans le forum Windows
    Réponses: 4
    Dernier message: 23/06/2005, 09h33
  4. Problème avec glutFullScreen() sous linux...
    Par MaxPayne dans le forum OpenGL
    Réponses: 1
    Dernier message: 29/11/2004, 11h30
  5. Problème avec CopyDir sous D5
    Par Houben Jacques dans le forum Langage
    Réponses: 3
    Dernier message: 26/05/2003, 22h02

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