obtenir un message d'erreur clair de PDO

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

05 nov. 2011, 20:29

B'soir,

Je test en ce moment php + PDO + oracle
ça se passe pas trop mal, mais bon les messages d'erreurs sont pas vraiment explicite :mrgreen:

mon script, prend un fichier csv et réalise les insertion dans la table (le fichier porte le nom de la table) via une requête préparé
ce qui donne :
<?php
$pdo = new PDO('oci:dbname=//localhost/kertaz;charset=UTF8', 'moogli', 'mdp');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->query('ALTER session SET nls_date_format = \'DD/MM/RRRR HH24:MI:SS\'');

    if (!empty($_POST['valid']) && $_POST['valid']=='Go' && !empty($_FILES['fichiers'])){
        // aller op on valid
        foreach ($_FILES['fichiers']['name'] as $index => $filename){
            if (!empty($filename) && $_FILES['fichiers']['error'][ $index ] === 0){
                echo 'Traitement du fichier : '.$filename.'<br />';
                //pour chaque fichier on récupére le contenu dans un tableau
                //nom du fichier $file['name'], le fichier physique $file['tmp_name']
                $f = file($_FILES['fichiers']['tmp_name'][$index]);
                $tblname = pathinfo($filename, PATHINFO_FILENAME);
                $entete = str_getcsv($f[0],';');
                $nb = count($entete);
                $sql = 'insert into '.$tblname.' ('.implode(',',$entete).') values (:'.implode(',:',$entete).')';
                // préparation de la requete
                var_dump($sql);
                $prepare = $pdo->prepare($sql);
                unset($f[0]);
                foreach ($f as $l ){
                    $l = trim($l);
                    if (!empty($l)){

                        //insertin des lignes dans la table qui va bien ok dès le début ? :)
                        $data = str_getcsv($l,';');
                        /**/
                        if ($prepare->execute($data) === true ) {
                            echo '<p class="notification">';
                            echo 'execution de : '.implode(',',$data).' =====> ';
                            echo 'ok</p>' ;
                        }
                        else {
                             echo '<div class="error_notification">';
                            echo 'execution de : '.implode(',',$data).' =====> KO<br />';
                            $e  = $prepare->errorInfo() ;
                            echo $e[2],'<hr />';
                            echo $prepare->debugDumpParams();
                            echo '<pre>';
                            var_dump($data);
                            echo '</pre>';
                            echo '</div>' ;
                        }
                        /* */
                    }// fin du if !empty
                }
            }
        }
        echo '</pre>';
    }
    
}
 catch (PDOException $e){
     echo '<div class="error_notification">Erreur dans le fichier '. $e->getFile().
             '<br />a la ligne : '.$e->getLine() .
             '<br /> '.$e->getMessage().'<br/>'.$e->getTraceAsString();
     if (isset($prepare)) {
         echo '<hr />';
         echo 'requete : ',$prepare->queryString;
         echo '<hr />';
         $err  = $prepare->errorInfo() ;
        echo $err[2],'<hr />';
        echo $prepare->debugDumpParams();
        echo '<pre>';
        var_dump($data);
        echo '</pre>';
     }
     if (isset($data)){
         echo implode(',',$data);
     }
     echo '</div>';
 }
?>
Le script fonctionne, par contre sur mon dernier fichier, j'ai une erreur assez peux compréhensible
SQLSTATE[HY000]: General error: 926 OCIStmtExecute: ORA-00926: missing VALUES keyword (ext\pdo_oci\oci_statement.c:148)
#0 H:\web\docRoot\oracle\index.php(55): PDOStatement->execute(Array) #1 {main}
requete : insert into papyrus-vente (CODART,NUMFOU,DELLIV,QTE1,PRIX1,QTE2,PRIX2,QTE3,PRIX3) values (:CODART,:NUMFOU,:DELLIV,:QTE1,:PRIX1,:QTE2,:PRIX2,:QTE3,:PRIX3)
OCIStmtExecute: ORA-00926: missing VALUES keyword (ext\pdo_oci\oci_statement.c:148)
SQL: [153] insert into papyrus-vente (CODART,NUMFOU,DELLIV,QTE1,PRIX1,QTE2,PRIX2,QTE3,PRIX3) values (:CODART,:NUMFOU,:DELLIV,:QTE1,:PRIX1,:QTE2,:PRIX2,:QTE3,:PRIX3) Params: 9 Key: Position #0: paramno=0 name=[0] "" is_param=1 param_type=2 Key: Position #1: paramno=1 name=[0] "" is_param=1 param_type=2 Key: Position #2: paramno=2 name=[0] "" is_param=1 param_type=2 Key: Position #3: paramno=3 name=[0] "" is_param=1 param_type=2 Key: Position #4: paramno=4 name=[0] "" is_param=1 param_type=2 Key: Position #5: paramno=5 name=[0] "" is_param=1 param_type=2 Key: Position #6: paramno=6 name=[0] "" is_param=1 param_type=2 Key: Position #7: paramno=7 name=[0] "" is_param=1 param_type=2 Key: Position #8: paramno=8 name=[0] "" is_param=1 param_type=2

-- résultat du str_getcsv
array(9) {
[0]=>
string(4) "B001"
[1]=>
string(4) "8700"
[2]=>
string(2) "15"
[3]=>
string(1) "0"
[4]=>
string(3) "150"
[5]=>
string(2) "50"
[6]=>
string(3) "145"
[7]=>
string(3) "100"
[8]=>
string(3) "140"
}
B001,8700,15,0,150,50,145,100,140 <= correspond a une ligne du fichier csv
oui c'est assez verbeux, mais en fait j'ai pas ce que je veux, a savoir la requête qui est envoyé a oracle au final :)

Lorsque j'ai ce message la connexion est ok, le prépare aussi, mais l'execute me crie le merdier du dessus :)

la requête préparée est faite ligne 43
$sql = 'insert into '.$tblname.' ('.implode(',',$entete).') values (:'.implode(',:',$entete).')';
et la j'le vois bien le values :)

Si quelqu'un avait une idée pour m'aider à trouver plus d'info dans PDO sur ce qui ne va pas (en fiat la requête et les données envoyées).
enfin pour être claire pas la requête préparé ça on l'a avec : PDOStatement::queryString, je voudrais ce qui est envoyé à oracle mais je sais pas comment l'avoir :/

je crois que j'ai fait le tour si z'avez des questions pas de soucis

mici

j'allais oublier :
le fichier csv
CODART;NUMFOU;DELLIV;QTE1;PRIX1;QTE2;PRIX2;QTE3;PRIX3
B001;8700;15;0;150;50;145;100;140
B002;8700;15;0;210;50;200;100;185
D035;120;0;0;40;;;;
D035;9120;5;0;40;100;30;;

la table
CREATE TABLE "MOOGLI"."VENTE"
  (
    "CODART" CHAR(4 BYTE) NOT NULL ENABLE,
    "NUMFOU" NUMBER(10,0) NOT NULL ENABLE,
    "DELLIV" NUMBER(6,0) NOT NULL ENABLE,
    "QTE1"   NUMBER(6,0) NOT NULL ENABLE,
    "PRIX1"  NUMBER(5,2) NOT NULL ENABLE,
    "QTE2"   NUMBER(6,0),
    "PRIX2"  NUMBER(5,2),
    "QTE3"   NUMBER(6,0),
    "PRIX3"  NUMBER(5,0),
    CONSTRAINT "VENTE_PK" PRIMARY KEY ("CODART", "NUMFOU") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "USERS" ENABLE,
    CONSTRAINT "FK_VENTE_FOURNIS" FOREIGN KEY ("NUMFOU") REFERENCES "MOOGLI"."FOURNIS" ("NUMFOU") ENABLE,
    CONSTRAINT "FK_VENTE_PRODUIT" FOREIGN KEY ("CODART") REFERENCES "MOOGLI"."PRODUIT" ("CODART") ENABLE
  )
@+
Modifié en dernier par moogli le 05 nov. 2011, 22:12, modifié 2 fois.
Il en faut peu pour être heureux ......

ViPHP
xTG
ViPHP | 7331 Messages

05 nov. 2011, 21:46

Cette erreur correspond à l'oubli du mot clé VALUES dans la requête, sauf qu'elle y est dans ton cas.
Le nom de la table est-il correct ? Un tiret ce n'est pas courant, peut être qu'il ne l'interprète pas correctement. Essayes d'échapper le nom de la table (tout du moins si cela existe en syntaxe Oracle).

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

05 nov. 2011, 22:11

merci xTG, en fait c'ets que je suis un gros boulet, le nom de fichier est pas bon (comme tu me l'a fait remarqué) la table c'est vente, papyrus c'est le nom du sujet ^^

bref un nom de table qui n'existe pas et la requête préparée passe nikel, j'étais trop concentré a chercher les valeurs pour voir cela.

Ceci dit le message d'erreur carrément à la rue la pour le coup.
me reste plus qu'a réglé mes problème de valeur qui rentre pas dans les champs (tas de données érronées) et ça roule ;)

merci à toi c'est trop con comme erreur :/
Il en faut peu pour être heureux ......

ViPHP
xTG
ViPHP | 7331 Messages

05 nov. 2011, 22:58

Les messages d'erreurs de PDO sont en effet bien trop souvent soit très incomplets, soit trop dans le vague, soit totalement à la rue.
On tombe souvent aussi sur celui là à cause d'erreurs à la c** :
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line
Bref ils auraient marqué "ERROR" que ça reviendrait au même...

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

05 nov. 2011, 23:06

wé, mais ça c'est des messages des sgbd :/

Enfin bref la pour le coup c'est vraiment con comme erreur :/
Il en faut peu pour être heureux ......