[RESOLU] Update sur une valeur BindValue

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [RESOLU] Update sur une valeur BindValue

Re: Update sur une valeur BindValue

par josse34 » 06 nov. 2013, 13:20

Bonjour!

En fait le souci venait de la PRIMARY KEY qui n'est pas bien configuré dans ma table, si je le fait manuellement tout roule! Les erreurs de MySQL pourraient être plus explicite tout de même!!! :mrgreen:

En fait je faisait une création de table et un déplacement dans la foulée, c'est dans ce déplacement qu'il faut détailler de nouveau les clefs :
  $creationtable1 = $connexion4->query("CREATE TABLE IF NOT EXISTS `$result1[$a]` (dtlog DATE PRIMARY KEY, glot INT);");
  $creationtable1->closeCursor();
  $copietable1 = $connexion4->query('CREATE TABLE cronmeteoarchives.'.$result1[$a].' (dtlog DATE PRIMARY KEY, glot INT) AS (SELECT * FROM cronmeteo.'.$result1[$a].')');
Merci!!!!!!

Re: Update sur une valeur BindValue

par josse34 » 05 nov. 2013, 21:27

Merci de ton aide, le tableau se présente comme suit (avec ces fichus doublons!) :

dtlog / glot
2013-11-04 / 414
2013-11-04 / 414
2013-11-03 / 1082
2013-11-03 / 1082

en sachant que : dtlog DATE PRIMARY KEY, glot INT

Re: Update sur une valeur BindValue

par xTG » 05 nov. 2013, 21:19

dtlog est-elle une clé ?

Re: Update sur une valeur BindValue

par josse34 » 05 nov. 2013, 21:12

Décidément, c'est incompréhensible pour moi!!!!!!
J'ai defini un second bind et essayé le duplicate key avec, le code tourne mais ne fait aucun update, j'ai encore des doublons ...
            $stmt = $pdo->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = str_to_date(:dt2,\'%Y%m%d\')');                                        

            if (count($tabFile) > 0) {
                unset($tabFile[0]);
                $i = 0;
                foreach ($tabFile as $line) {
                    $csv = str_getcsv($line, ';');
                    $stmt->bindValue(':dt', $csv[1]);
                    $stmt->bindValue(':dt2', $csv[1]);                    
                    $stmt->bindValue(':glot', $csv[2], PDO::PARAM_INT);                
                    $stmt->execute();                    
                    $testtable1->closeCursor();
                    $i++;
                    rename($tmpFolder . $fileinfo->getFilename(), $finalFolder . $fileinfo->getFilename());
                }
            }
Pourquoi bon sang?!
Merci!

Re: Update sur une valeur BindValue

par xTG » 05 nov. 2013, 19:27

Non quand je parlais d'un second bind c'était avec une seconde variable :
$stmt = $pdo->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = str_to_date(:dt2,\'%Y%m%d\')'); 
Avec dt2 = dt.

Re: Update sur une valeur BindValue

par josse34 » 05 nov. 2013, 17:25

Je n'ai que ce bind en date, néanmoins si j'essaye avec un bind non formaté comme ceci :
$stmt = $pdo->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = :dt'); 
Erreur :
SQLSTATE[HY093]: Invalid parameter number #0 CRONMETEO.php(44): PDOStatement->execute()
#1 {main}
Si je me base sur ce topic, on ne peut réutiliser deux fois un bind dans une requete MySQL : http://stackoverflow.com/questions/7838 ... -statement
Mais si je fais simplement :
$stmt = $pdo->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = VALUES(dtlog)'); 
, le code ne bloque pas mais insère sans update, je me retrouve donc avec des doublons.

:?

Re: Update sur une valeur BindValue

par xTG » 05 nov. 2013, 17:13

Et si tu remplaces par un autre bind pour le duplicate ?
Et en essayant de formater la date via PHP avant de l'injecter ?

Re: Update sur une valeur BindValue

par josse34 » 05 nov. 2013, 16:45

Slu!
Ca ne fonctionne pas, le code bloque :
$stmt = $pdo->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = \'str_to_date(:dt,\'%Y%m%d\')\'');
Erreur :
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 1 #0 CRONMETEO.php(35): PDO->prepare('INSERT INTO `44...')
#1 {main}
et d'ailleurs après réflexion mon code initial ci-dessous devrait logiquement fonctionner puisque str_to_date(:dt,\'%Y%m%d\') est déjà dans les valeurs :
$stmt = $pdo->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = str_to_date(:dt,\'%Y%m%d\')');
Erreur :
SQLSTATE[HY093]: Invalid parameter number #0 CRONMETEO.php(44): PDOStatement->execute() #1 {main}
Vraiment je ne comprend pas pourquoi ca fonctionne dans les VALUES et pas dans le ON DUPLICATE KEY, la tablea à bien une primary key : dtlog DATE PRIMARY KEY, glot INT

Voici le code complet :
<?php
    try {
    $pdo = new PDO('mysql:host=localhost;dbname=cronmeteo', 'cronmeteo', 'PASSWORD');
    $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
    $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
    $pdo->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER);
    
    $pdo2 = new PDO('mysql:host=localhost;dbname=cronmeteoarchives', 'cronmeteo', 'PASSWORD');
    $pdo2->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    $pdo2->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
    $pdo2->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
    $pdo2->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER);

    $tmpFolder = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
    $finalFolder = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'archives' . DIRECTORY_SEPARATOR;
    $originalDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'publitheque' . DIRECTORY_SEPARATOR;

    $dir = new DirectoryIterator($originalDir);
    foreach ($dir as $fileinfo) {
 
        if (!$fileinfo->isDot() && $fileinfo->isFile() && pathinfo($fileinfo->getFilename(), PATHINFO_EXTENSION) == 'data') {

            rename($originalDir . $fileinfo->getFilename(), $tmpFolder . $fileinfo->getFilename());

            $tabFile = file($tmpFolder . $fileinfo->getFilename());
            preg_match('/^fic(\d+)-(\d+)-(\d+)-(\d+).data$/', $fileinfo->getFilename(), $match);
            $table = $match[1];
            
            $testtable1 = $pdo->query("SHOW TABLES LIKE '$table'");
            $testtable2 = $pdo2->query("SHOW TABLES LIKE '$table'"); 
            
            if ($testtable1->rowCount()>0){ 
            
            $stmt = $pdo->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = dtlog');

            if (count($tabFile) > 0) {
                unset($tabFile[0]);
                $i = 0;
                foreach ($tabFile as $line) {
                    $csv = str_getcsv($line, ';');
                    $stmt->bindValue(':dt', $csv[1]);
                    $stmt->bindValue(':glot', $csv[2], PDO::PARAM_INT);                   
                    $stmt->execute();                    
                    $testtable1->closeCursor();
                    $i++;
                    rename($tmpFolder . $fileinfo->getFilename(), $finalFolder . $fileinfo->getFilename());
                }
            }
          }elseif ( $testtable2->rowCount()>0){ 
            
            $stmt = $pdo2->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = dtlog');

            if (count($tabFile) > 0) {
                unset($tabFile[0]);
                $i = 0;
                foreach ($tabFile as $line) {
                    $csv = str_getcsv($line, ';');
                    $stmt->bindValue(':dt', $csv[1]);
                    $stmt->bindValue(':glot', $csv[2], PDO::PARAM_INT);                   
                    $stmt->execute();                    
                    $testtable2->closeCursor();
                    $i++;
                    rename($tmpFolder . $fileinfo->getFilename(), $finalFolder . $fileinfo->getFilename());
                }
            }
          }else{rename($tmpFolder . $fileinfo->getFilename(), $finalFolder . $fileinfo->getFilename());}
        }        
    }
} catch (Exception $e) {
    $to = 'MAIL';
    $subject = 'ALERTE CRON METEO';
    $msg = 'Attention, interruption du CRON meteo :     '.$e->getMessage().'     '.$e->getTraceAsString().'';
    mail($to, $subject, $msg);
}

Re: Update sur une valeur BindValue

par xTG » 05 nov. 2013, 12:51

Une date est une chaîne de caractère et dont requiert des simples quotes je dirai.
A tester ? :o

Code : Tout sélectionner

dtlog = \'str_to_date(:dt,\'%Y%m%d\')\'

Update sur une valeur BindValue

par josse34 » 05 nov. 2013, 12:09

Bonjour!
Je n'arrive pas à faire un ON DUPLICATE KEY UPDATE sur une valeur en bindvalue :
$stmt = $pdo->prepare('INSERT INTO `' . $table . '` (dtlog, glot) VALUES (str_to_date(:dt,\'%Y%m%d\'),:glot) ON DUPLICATE KEY UPDATE dtlog = str_to_date(:dt,\'%Y%m%d\')');
Le code fonctionne très bien sans la partie update mais sachant que :dt (initialement 20131105) est la valeur de dtlog (en 2013-11-05) comme ceci : stmt->bindValue(':dt', $csv[1]); quelle est la bonne syntaxe? Tout ceci ne fonctionne pas :
ON DUPLICATE KEY UPDATE dtlog = values(dtlog)
ON DUPLICATE KEY UPDATE dtlog = values(:dt)
ON DUPLICATE KEY UPDATE dtlog = str_to_date(:dt,\'%Y%m%d\')
ON DUPLICATE KEY UPDATE dtlog = values(str_to_date(:dt,\'%Y%m%d\'))

Merci!!!!!!