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 :

PHP / Oracle : récupérer ID auto incrémente sur un INSERT


Sujet :

SQL Oracle

  1. #1
    Futur Membre du Club
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut PHP / Oracle : récupérer ID auto incrémente sur un INSERT
    Bonjour / Bonsoir à tous

    Je travaille actuellement sur une base Oracle à partir de php5.
    Mon problème actuel est de récupérer l'ID d'un nouvel enregistrement lors d'un INSERT.

    Soit une table Oracle de la forme :

    maTable
    ----------------
    | id | strValue |
    ----------------
    J'ai également un trigger et une séquence liée à cette table pour gérer l'auto incrémente (tout ça fonctionne).

    J'aimerai donc avoir un code de la sorte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $sql = "INSERT INTO 
    maTable (id, strValue) 
    VALUES (sq_matable.NEXTVAL, 'strNulle')
    RETURNING ID INTO :myId"
     
    $stmt = oci_parse($connectOracle, $sql);
    oci_bind_by_name($statement, ':myId', $myId);
    oci_execute($stmt , OCI_DEFAULT);
    oci_free_statement($stmt );
     
    echo $myId;
    Mon problème est que ma variable $myId ne contient QUE les 3 premiers charactères de la valeur attendue.
    En revanche, si j'initialise ma variable avant de lui affecter la valeur retournée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $myId=0123456789;
    oci_bind_by_name($statement, ':myId', $myId);
    Alors ma variable contient bien la valeur de mon ID.

    Il semblerai donc qu'il s'agisse d'un problème d'allocation de mémoire du côté de PHP.
    Mais je ne sais pas comment initialiser ma variable avec une taille fixe ou variable pour être sûre de récupérer la valeur de cet ID même dans 10 ans (quand l'incrément aura atteind des valeurs très grandes).
    Existe-t-il donc une façon de faire pour récupérer ce fameux ID ?

    Merci à tous ceux qui pourront m'aider

  2. #2
    Expert éminent sénior 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
    Points : 11 252
    Points
    11 252
    Par défaut
    Je pense que vous en faite trop; l'insert incrémente la séquence donc que est-ce que le trigger fait ?
    Pourriez-vous ajouter aussi le code du trigger ?

  3. #3
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Bonjour,
    Ceci répond t-il à votre question

    select sq_matable.CURRVAL from dual;


    Cordialement,

  4. #4
    Futur Membre du Club
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    @mnitu
    Voici le trigger lié à ma table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create or replace TRIGGER TRG_maTable_ID
        BEFORE INSERT
        ON maTable
        FOR EACH ROW
        WHEN (OLD.ID IS NULL)
    BEGIN
        SELECT SEQ_maTable.NEXTVAL INTO :NEW.ID FROM DUAL;
    END;
    Je sais que j'ai pas besoin d'utiliser ma séquence dans ma requête, mais c'était uniquement pour pouvoir récupérer l'ID auto incrémente à la fin de la requête.

    @Xuan-Khanh
    Celà revient un peu à ma solution actuelle qui est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function getNextID($connectOracle)
    {
      $queryOracle = "SELECT SEQ_maTable.NEXTVAL FROM DUAL"; 
      $statement = oci_parse($connectOracle, $queryOracle);
      oci_execute ($statement, OCI_DEFAULT) or print_r( oci_error($statement) );  
      $dataOracle = oci_fetch_assoc($statement);
      return $dataOracle['NEXTVAL'];
    }
    Et ma requête actuelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $newID = getNexID($connectOracle);
    $sql = "INSERT INTO 
    maTable (id, strValue) 
    VALUES (".$newID .", 'strNulle')
    RETURNING ID INTO :myId"
     
    $stmt = oci_parse($connectOracle, $sql);
    oci_execute($stmt , OCI_DEFAULT);
    oci_free_statement($stmt );
     
    echo $newID;
    Et donc je n'évite pas l'exécution d'une deuxième requête pour récupérer ce fameux ID...

  5. #5
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    eventuellement tu peux faire une fonction qui fait l'insert avec NEXTVAL et qui retourne CURRVAL

  6. #6
    Futur Membre du Club
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Merci de la réponse... mais je ne sais pas comment créer cette fonction NI comment l'utiliser ensuite dans ma requête...

    Pourriez-vous me renseigner ?

    N'existe-t-il donc aucuen fonction php5/Oracle me permettant d'emuler un tel fonctionnement ? :'(

  7. #7
    Futur Membre du Club
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Suite de mes investigations...
    Oracle
    Soit la séquence suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    REM START GED SEQ_maTable
       CREATE SEQUENCE  "maCon"."SEQ_maTable"  MINVALUE 1 MAXVALUE 9999999999 INCREMENT BY 1 START WITH 1 CACHE 20 ORDER  NOCYCLE ; 
    REM END GED SEQ__maTable
    Soit le trigger suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create or replace TRIGGER TRG_maTable_ID
        BEFORE INSERT
        ON maTable
        FOR EACH ROW
        WHEN (OLD.ID IS NULL)
    BEGIN
        SELECT SEQ_maTable.NEXTVAL INTO :NEW.ID FROM DUAL;
    END;
    PHP5
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $queryOracle = 
    "INSERT INTO maTable ( myData ) 
    VALUES ( 'something' )
    RETURNING ID, DATA INTO :ID, :DATA"; 
    $stmt= oci_parse($connectOracle, $queryOracle);
     
    oci_bind_by_name($stmt, ':ID', $ID, 2);
    oci_bind_by_name($stmt, ':CODECLIENT', $DATA, 2);
     
    oci_execute($stmt, OCI_DEFAULT);
    oci_free_statement($stmt);
     
    echo "ID : $ID - CODECLIENT: $DATA\n";
    Cette fois, plus de problème.
    J'ai les valeurs comme je le souhaite.

    Seulement, je ne sais pas quelle taille indiquer pour oci_bind_by_name() pour être sûre de toujours avoir la valeur entière de mon ID.

    Je ne comprends pas pourquoi avec une taille de 1, mon ID est tronqué sur les 3 premiers chars, alors que avec lenght=2, il est retourné en entier...
    Quelqu'un pourrai-t-il m'expliquer un peu plus que la doc PHP sur cette valeur ?

    Merci à vous.

  8. #8
    Expert éminent sénior 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
    Points : 11 252
    Points
    11 252
    Par défaut
    Est-ce que tu peut essayer ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    oci_bind_by_name($stmt, ':ID', $ID, -1, SQLT_INT);

  9. #9
    Futur Membre du Club
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PHP Notice:  Use of undefined constant SQLT_INT - assumed 'SQLT_INT'
    Et me fais planter php

    je vais laisser ma solution sus-cité, sans savoir le pourquoi du comment ;'(

  10. #10
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par wisrou Voir le message
    @mnitu
    Voici le trigger lié à ma table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create or replace TRIGGER TRG_maTable_ID
        BEFORE INSERT
        ON maTable
        FOR EACH ROW
        WHEN (OLD.ID IS NULL)
    BEGIN
        SELECT SEQ_maTable.NEXTVAL INTO :NEW.ID FROM DUAL;
    END;
    La clause est fausse !
    En INSERT, le OLD vaut toujours NULL (c'est normal, il n'y a aucune donnée en base).
    Donc tu fais toujours le select.

    Il faut mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create or replace TRIGGER TRG_maTable_ID
        BEFORE INSERT
        ON maTable
        FOR EACH ROW
        WHEN (NEW.ID IS NULL)
    BEGIN
        SELECT SEQ_maTable.NEXTVAL INTO :NEW.ID FROM DUAL;
    END;

  11. #11
    Expert éminent sénior 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
    Points : 11 252
    Points
    11 252
    Par défaut
    Mon expérience en PHP est nulle mais à ta place je ne laisserai pas passer cette chose comme ça.
    Essayez en attendent qu’un maître du PHP siffle la fin de la recréation
    a) en supprimant le trigger sur la table et utiliser nextval et currval
    b) en gardant le trigger sur la table et supprimer le nextval dans l’insert
    Dans le deux cas utilisez oci_bind_by_name($stmt, ':ID', $ID) ;

  12. #12
    Futur Membre du Club
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    @McM : merci de cette précision.
    Comme j'ai jamais manipulé de bases Oracle, je fais plus du recopie... ^^"

    @mnitu : je vais essayer tes deux propositions, mais je pense pas pouvoir encore perdre plus de temps sur ce #$£&! problème
    J'ai une mise en recette et en prod qui approche

Discussions similaires

  1. [Etats & Requêtes] Récupérer le dernier auto incrément sur base SQL Server
    Par droliprane dans le forum WinDev
    Réponses: 6
    Dernier message: 25/05/2013, 16h16
  2. [WD14] Auto-incrémentation sur table mémoire
    Par BENKOUIDER dans le forum WinDev
    Réponses: 1
    Dernier message: 02/08/2009, 13h17
  3. auto incrément sur deux champs
    Par mdordenart dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 15/07/2009, 08h56
  4. auto-incrémentation sur une primary key avec sql server
    Par pops4 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 24/05/2007, 14h24
  5. [JDBC] [ORACLE] Récupérer Id auto-inséré ???
    Par Bobsinglar dans le forum JDBC
    Réponses: 4
    Dernier message: 30/05/2005, 16h13

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