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

SGBD Perl Discussion :

[DBI] Insertion de donnees


Sujet :

SGBD Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de bambou
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2004
    Messages : 192
    Par défaut [DBI] Insertion de donnees
    Bonjour,

    J'essaye d'insere des tuples dans une base de donnees, pour cela j'utilise DBI..

    Je souhaiterai savoir si je suis oblige de faire un SELECT avant mon INSERT pour verifier si le tuple exite ou non, ou si je peux passer par les messages d'erreurs renvoyes par la BD pour verifier ca...Sachant que l'autocommit est a 0
    et de meme il y a t il un moyen de recuperer la cle primaire apres l'insertion d'un tupple sans avoir a repasser par un SELECT dans le cas d'une table avec une cle primaire en integer auto-incremente?

    Merci,

    Je vous laisse mon code...qui ne marche pas

    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
    eval{
      $db = DBI -> connect($dsn,$dbUser,$dbPwd, { RaiseError => 1, AutoCommit => 0,PrintError=>1 });
     };
     
    if($DBI::state != undef){
      push(@errors, [$DBI::state, $DBI::errstr, " Connexion Error"]);
    }
     
     eval{
        $req = $db->prepare("INSERT INTO Organisation (Name) values(\'$organisation\')");
        $req->execute();
      };
      if($DBI::state != '23505' && $DBI::state != undef && $DBI::state != '25P02'){ 
        push(@errors, [$DBI::state, $DBI::errstr, "INSERT INTO Organisation (Name) values(\'$organisation\')"]);
      }
     
      if(@errors > 0){
        my $j;
        for($j=0;$j<scalar(@errors);$j++){
          print LOG_FILE "count=".@errors."\n";
          print LOG_FILE "--------------------------------------------------\n";
          print LOG_FILE "Error Code : ".$errors[$j][0]."\n";
          print LOG_FILE "Error : ".$errors[$j][1]."\n";
          print LOG_FILE "Remark : ".$errors[$j][2]."\n";
          print LOG_FILE "--------------------------------------------------\n";
        }
        if($db){
          $db->rollback;
          $req->finish();
          $db->disconnect(); 
          exit_ui(0);
        }
      }else{
        $db->commit;
        $req->finish();
        $db->disconnect(); 
      }
    $DBI::state != '23505' => Duplicate key
    $DBI::state != '25P02' => Operation aborded (renvoye quand on essaye de passer une requete et qu'une erreur s'est produite sur une requete precedante, les requetes suivant l'erreurs sont "aborded" en mode autocommit a 0

    voila, ce code est un test pour eviter de faire des Select count(*) avant pour tester si le tupple a inserer exite...je le trouve pas tres joli et i marche pas de toute facon, parce que postgre annule systematiquement toutes les requetes suivant celle qui a une cle primaire deja existante...

    j'espere avoir etait comprehensible...

    Merci pour votre aide!

  2. #2
    Membre expérimenté Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Par défaut
    Pour commencer, l'appel de finish() ne se fait que dans des conditions particulières :
    finish

    $rc = $sth->finish;

    Indicates that no more data will be fetched from this
    statement handle before it is either executed again or
    destroyed. The finish method is rarely needed, but can
    sometimes be helpful in very specific situations to
    allow the server to free up resources (such as sort
    buffers).

    When all the data has been fetched from a SELECT
    statement, the driver should automatically call finish
    for you. So you should not normally need to call it
    explicitly except when you know that you've not fetched
    all the data from a statement handle.
    The most common
    example is when you only want to fetch one row, but in
    that case the selectrow_* methods may be better anyway.
    Ensuite, pense à bannir les for() à la sauce langage C, ils ne sont utiles que dans certains cas particuliers en PERL, et sont plus illisibles que la syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach my $j ( 0..scalar(@errors) )
    {
    }
    (ici le scalar est inutile en plus, puisque @errors est déjà utilisé dans un contexte scalaire )

    En plus je ne vois pas l'intérêt de tous ces "eval"...

    Sinon, pour ton problème de clef primaire, je ne connais pas d'autre manière que le select, qui te retournera si la clef existe déjà en table ou non.
    C'est normalement une requête à l'exécution très rapide, puisqu'il y a, enfin j'espère, un index sur l'ensemble des champs formant la clef.

    Tu mets cette requête dans une fonction qui retourne 1 ou 0 selon que la clef existe ou non, et le tour est joué.
    Ce qui ne t'empêche pas de vérifier les résultats de l'insertion...

    Dernière chose, j'assume que ton script ne comprend qu'une seule connexion+déconnexion. Si ce n'est pas le cas, tu devrais : la connexion est une étape coûteuse...

    Là, comme ça vite fait, j'écrirais ça comme ça :
    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
    my $db = DBI->connect($dsn,$dbUser,$dbPwd, { RaiseError => 1, AutoCommit => 0,PrintError=>1 });
     
    if ( defined($db) )
    {
       my @clef_exists = $db->selectrow_array("select count(*) from Organisation where <clef primaire machin>");
     
       if ( $clef_exists[0] == 0 )
       {
          $db->do("INSERT INTO Organisation (Name) values(\'$organisation\')");
          # ...tu peux toujours vérifier que ça s'est bien passé ici ...
     
          $db->commit();
       }
       else
       {
           # Ca, ou alors recommencer avec une autre clef...
           push(@errors, "Clef déja existante");
       }
     
       $db->disconnect(); 
    }
    else
    {
        push(@errors, [$DBI::state, $DBI::errstr, " Connexion Error"]);
    }
     
     
    if ( @errors > 0 )
    {
       print LOG_FILE "count=".@errors."\n";
     
       foreach my $j ( 0..@errors )
       {
          print LOG_FILE "--------------------------------------------------\n";
          print LOG_FILE "Error Code : ".$errors[$j][0]."\n";
          print LOG_FILE "Error : ".$errors[$j][1]."\n";
          print LOG_FILE "Remark : ".$errors[$j][2]."\n";
          print LOG_FILE "--------------------------------------------------\n";
       }
    }

  3. #3
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 606
    Par défaut
    Citation Envoyé par Gamdwin
    En plus je ne vois pas l'intérêt de tous ces "eval"...
    Ben, un eval n'a d'intérêt que si l'on pense à tester derrière ce qu'il retourne dans $@. Sinon, effectivement...

  4. #4
    Membre confirmé Avatar de bambou
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mars 2004
    Messages : 192
    Par défaut
    Ok merci, c'est deja un peu plus clair sur le principe...

    Pour le eval je fesais un test sur le $@, mais je l'ai enleve hier pour le remplacer par le test sur le DBI::state, donc je vais enlever tout ce bouzin et refaire un truc plus propre

    merci a tous les deux!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Insertion de données en arabe sur Mysql
    Par mkachekh dans le forum Outils
    Réponses: 4
    Dernier message: 11/06/2009, 13h37
  2. lenteur dans l'insertion de donnees en 10Gr2
    Par JUSTIN Loïc dans le forum SQL
    Réponses: 55
    Dernier message: 22/09/2006, 20h55
  3. [SQL] probleme insertion de donnees
    Par zorian dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 19/06/2006, 22h17
  4. Réponses: 11
    Dernier message: 01/06/2005, 16h18
  5. [C#][SQL Server] Insertion de données inversées
    Par lamiae18 dans le forum ASP.NET
    Réponses: 7
    Dernier message: 20/04/2004, 17h11

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