errore con mysql insert in PDO

3_g

Utente Attivo
5 Set 2017
36
1
8
Ancona
devo leggere un file di testo (delimitato) e inserire le righe nei campi di un DB... e non ci sarebbe niente di strano se non fosse che la query se inserita in mysql... funziona, inserita in uno script php...no:(
il file da leggere è questo:
101|0|"Nome Cognome"|"Citta"|1|0|0|0.0|0|0|0.0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1

sono in tutto 28 valori di diverso tipo, principalmente integer poi float e testo
PHP:
$camp=23;
$textarray=file("file.txt");

for($i=0; $i<count($textarray); $i++)
{
  $text=substr($textarray[$i],0,-1);

  list($var1,$var2,$var3,$var4,$var5,$var6,$var7,$var8,$var9,$var10)=explode('|',$text);

  $database->query('INSERT INTO Tabella VALUES (
  \'\',
  :camp,
  :var1,
  :var2,
  :var3,
  :var4,
  :var5,
  :var6,
  :var9,
  :var10)');

//  $database->bind(':id', 100);
  $database->bind(':camp', $camp);
  $database->bind(':var1', $var1);
  $database->bind(':var2', $var2);
  $database->bind(':var3', str_replace('"', '', $var3));
  $database->bind(':var4', str_replace('"', '', $var4));
  $database->bind(':var5', $var5);
  $database->bind(':var6', $var6);
  $database->bind(':var9', $var9);
  $database->bind(':var10', $var10);

  $database->execute();
}

questo l'errore:
Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'ID_Dati' at row 1

questo è l'errore generato cercando di inserire un valore nullo per il campo autoicrementale


PHP:
$database->query('INSERT INTO TB_DatiGiornate VALUES (
  :id,
  :camp,
.........
 $database->bind(':id', 100);
 $database->bind(':camp', $camp);

... questo cercando di inserire un valore nel campo autoincrementale:
Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '100' for key 'PRIMARY'

PHP:
  $database->query('INSERT INTO TB_DatiGiornate VALUES (
  :camp,
..............
  $database->bind(':camp', $camp);

questo cercando di fare inserire automaticamente il valore del campo autoincrementale:
Fatal error: Uncaught PDOException: SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1


PRECISAZIONI:
- per semplicità ho importato solo i primi 10 valori del file di testo;
- la tabella ha 2 ulteriori campi: ID_Dati (campo autoincrementale e camp che va valorizzato con la variabile $camp)
- ho fatto le prove anche specificando la lista completa dei campi della tabella (con e senza il campo autoincrementale)
Codice:
INSERT INTO Tabella (ID_Dati, Camp, var1, var2, var3, var4, var5, var6, var9, var10) VALUES (':id', :camp, :var1, :var2, :var3, :var4, :var5, :var6, :var9, :var10)');

oppure

INSERT INTO Tabella (Camp, var1, var2, var3, var4, var5, var6, var9, var10) VALUES (':camp, :var1, :var2, :var3, :var4, :var5, :var6, :var9, :var10)');

...di prove ne ho fatte tante ma non ho trovato quella giusta... avete qualche idea?:rolleyes:
 

macus_adi

Utente Attivo
5 Dic 2017
1.343
91
48
IT/SW
Solitamente l'autoincrement non si valorizza ma si lascia la gestione dello stesso al DBMS, infatti come vedi l'errore della seconda è
Integrity constraint violation: 1062 Duplicate entry '100' for key 'PRIMARY'
ossia la chiave primaria è duplicata, in questo caso mi pare di capire che stai settando id=100 ma è già presente...

Detto questo, per la prima parte:

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'ID_Dati' at row 1

In questa porzione hai commesso errore di binding ossia nell'insert sono presenti 10 bind, ma tu ne passi solo 9...
Potresti abbreviare la tua query utilizzando un ciclo il che sarebbe molto più comoda la gestione:

PHP:
$values=explode('|',$text);

unset($values[0]);//elimino ID autoincrementale

$map_items=['camp','var1','var2','var3','var4','var5','var6','var7','var8','var9','var10'];
$compile_items=[];
//in questo modo mappi automaticamente i dati attraverso un'array associativo, per effettuare il bind
$query='INSERT INTO Tabella';
$type='';
$inter_=[];
foreach($map_items as $k=>$v){
$compile_items[$v]=$values[$k+1];
//non è lo scopo corretto lo inserisco solo a scopo illustrativo, dovrebbe essere processato da un QB apposito e no da iterazione
$inter_[]='?';
switch($k){
 //da implementare la tipologia per il binding
/*sarebbe utili reperire la tipologia dei dati sul db in modo automatico passando la tipologia creando un querybuilder o utilizzandone uno già pronto*/
    default:$type.='i';
}
}
//in questo modo la nostra query si costruisce in automatico
$query.='('.join(',',array_keys($compile_items)).') VALUES ('.join(',',$inter_)).')';

$this->conn->execute_stmt($query,$compile_items,$type)->result;

Per effettuare il binding qua ci sta un metodo:
https://forum.mrw.it/threads/php-ricerca-record-tramite-post.52470/#post-204377


Potresti pensare di utilizzare qualche lib o framework di supporto per la gestione e lavorazione dei dati.. medoo.in (https://medoo.in/) non è affatto male.
 

3_g

Utente Attivo
5 Set 2017
36
1
8
Ancona
ma la prova lasciando che il campo si valorizzasse da solo l'ho fatta (non ho riportato l'errore:() ma non funziona lo stesso
INSERT INTO Tabella (Camp, var1, var2, var3, var4, var5, var6, var9, var10) VALUES (':camp, :var1, :var2, :var3, :var4, :var5, :var6, :var9, :var10)');
questa sera la faccio "girare" e riporto l'errore

il valore '100' non è presente (la tabella ha 1 solo record registrato) l'ho inserito di proposito per "vedere" cosa succedeva...

non ho ancora padronanza del PHP per cui cerco di fare le cose semplici... e non mi riescono neanche quelle:(:(
il tuo codice e molto più efficiente ma vorrei aspettare di implementarlo per capire prima dove è l'errore nella mia query;)

nel 1 caso il binding corrisponde (9 su 9) il primo valore \'\' è per passare un valore nullo al campo autoincrementale per far si che sia il DBMS a metterlo... ho fatto la prova anche togliendo questo "valore" e lasciando solo i 9 binding...
diciamo che di prove/combinazioni (anche ad minchiam:eek:) ne ho fatte tante... perchè finite le soluzioni "logiche" per me... ho iniziato ad andare nel pallone:D
 

macus_adi

Utente Attivo
5 Dic 2017
1.343
91
48
IT/SW
nel 1 caso il binding corrisponde (9 su 9) il primo valore \'\' è per passare un valore nullo al campo autoincrementale per far si che sia il DBMS a metterlo...
in realtà no, l'autoincrement non dovrebbe essere passato.

Prova a creare una tabella senza autoincrement e senza vincoli vedi cosa succede.... se i dati vengono inseriti è come ti dico io....
 

3_g

Utente Attivo
5 Set 2017
36
1
8
Ancona
già provato;)
rimane il fatto che la query inserita in mysql funziona... messa con il PDO/binding... no

forse ci sono dei parametri da tener conto in base a come è fatta la tabella... stasera vi posto la struttura... precisa:)
 

3_g

Utente Attivo
5 Set 2017
36
1
8
Ancona
mi è venuto un dubbio... nella classe che uso (presa su interneto_O) la funzione bind è fatta così:
PHP:
    // funzione bind
    public function bind($param, $value, $type = null) {
        if (is_null($type)) {
            switch (true) {
                case is_int($value):
                    $type = PDO::PARAM_INT;
                    break;
                case is_bool($value):
                    $type = PDO::PARAM_BOOL;
                    break;
                case is_null($value):
                    $type = PDO::PARAM_NULL;
                    break;
                default:
                    $type = PDO::PARAM_STR;
            }
        }
        $this->stmt->bindValue($param, $value, $type);
    }

il problema di inserimento può derivare da questa??
 

3_g

Utente Attivo
5 Set 2017
36
1
8
Ancona
prove in diretta:eek:...
struttura delle tabelle del db:
PHP:
CREATE TABLE `Tabella1` (
  `ID_Dati` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `Camp` int(11) NOT NULL,
  `field1` tinyint(4) DEFAULT NULL,
  `field2` varchar(100) DEFAULT NULL,
  `field3` varchar(20) DEFAULT NULL,
  `field4` tinyint(4) DEFAULT NULL,
  `field5` float DEFAULT NULL,
  `field6` tinyint(4) DEFAULT NULL,
  `field7` int(11) DEFAULT NULL
) ENGINE=InnoDB;

CREATE TABLE `Tabella2` (
  `Camp` int(11) NOT NULL,
  `field1` tinyint(4) DEFAULT NULL,
  `field2` varchar(100) DEFAULT NULL,
  `field3` varchar(20) DEFAULT NULL,
  `field4` tinyint(4) DEFAULT NULL,
  `field5` float DEFAULT NULL,
  `field6` tinyint(4) DEFAULT NULL,
  `field7` int(11) DEFAULT NULL
) ENGINE=InnoDB;

dati da inserire (file.txt):
Codice:
101|"Nome Cognome"|"citta"|1|0.0|5|1
102|"Nome Cognome"|"citta"|2|0.1|4|1
103|"Nome Cognome"|"citta"|3|0.2|3|1
104|"Nome Cognome"|"citta"|4|0.3|2|1
105|"Nome Cognome"|"citta"|5|0.4|1|1

codice "fisso" dello script (la parentesi graffa di chiusura del for è riportata alla fine dello script:
PHP:
$database = new Database($db, $u, $p);

$camp=23;
$textarray=file("file.txt");

for($i=0; $i<count($textarray); $i++)
{
  $text=substr($textarray[$i],0,-1);

  list($var1,$var2,$var3,$var4,$var5,$var6,$var7)=explode('|',$text);

1^ prova effettuata con questa query:
PHP:
  $database->query('INSERT INTO Tabella1 VALUES (:camp, :var1, :var2, :var3, :var4, :var5, :var6, :var7)');

  $database->bind(':camp', $camp);
  $database->bind(':var1', $var1);
  $database->bind(':var2', str_replace('"', '', $var2));
  $database->bind(':var3', str_replace('"', '', $var3));
  $database->bind(':var4', $var4);
  $database->bind(':var5', $var5);
  $database->bind(':var6', $var6);
  $database->bind(':var7', $var7);

  $database->execute();

errore generato:
Fatal error: Uncaught PDOException: SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1
 

3_g

Utente Attivo
5 Set 2017
36
1
8
Ancona
2^ prova effettuata con questa query:
PHP:
  $database->query('INSERT INTO Tabella2 VALUES (:camp, :var1, :var2, :var3, :var4, :var5, :var6, :var7)');
 
  $database->bind(':camp', $camp);
  $database->bind(':var1', $var1);
  $database->bind(':var2', str_replace('"', '', $var2));
  $database->bind(':var3', str_replace('"', '', $var3));
  $database->bind(':var4', $var4);
  $database->bind(':var5', $var5);
  $database->bind(':var6', $var6);
  $database->bind(':var7', $var7);

  $database->execute();

FUNZIONA:)
 

3_g

Utente Attivo
5 Set 2017
36
1
8
Ancona
3^ prova effettuata con questa query:
PHP:
  $database->query('INSERT INTO Tabella1 (ID_Dati, Camp, field1, field2, field3, field4, field5, field6, field7) VALUES ('', :camp, :var1, :var2, :var3, :var4, :var5, :var6, :var7)');

  $database->bind(':camp', $camp);
  $database->bind(':var1', $var1);
  $database->bind(':var2', str_replace('"', '', $var2));
  $database->bind(':var3', str_replace('"', '', $var3));
  $database->bind(':var4', $var4);
  $database->bind(':var5', $var5);
  $database->bind(':var6', $var6);
  $database->bind(':var7', $var7);

  $database->execute();
errore generato:
Parse error: syntax error, unexpected '', :camp, :var1, :var2, :var3,' (T_CONSTANT_ENCAPSED_STRING), expecting ',' or ')'
 

3_g

Utente Attivo
5 Set 2017
36
1
8
Ancona
4^ prova effettuata con questa query:
PHP:
  $database->query('INSERT INTO Tabella1 (Camp, field1, field2, field3, field4, field5, field6, field7) VALUES (:camp, :var1, :var2, :var3, :var4, :var5, :var6, :var7)');

  $database->bind(':camp', $camp);
  $database->bind(':var1', $var1);
  $database->bind(':var2', str_replace('"', '', $var2));
  $database->bind(':var3', str_replace('"', '', $var3));
  $database->bind(':var4', $var4);
  $database->bind(':var5', $var5);
  $database->bind(':var6', $var6);
  $database->bind(':var7', $var7);

  $database->execute();
FUNZIONA CON QUESTA STRUTTURA DI DATI;);)... semplificata per fare le prove... ma con i dati "veri" no:confused::confused:

la caccia continua:D:D:D
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
1^ prova effettuata con questa query:
dovresti rifare la prova scrivendo bene la query,
considera anche la differenza tra virgolette e apici ….
Codice:
$database->query("
INSERT INTO Tabella1
(Camp, field1, field2, field3, field4, field5, field6, field7)
VALUES
(:camp, :var1, :var2, :var3, :var4, :var5, :var6, :var7)
");

se non indichi i campi della tabella, come nel tuo esempio, il motore del db potrebbe "confondersi" perché ha un campo in più, l'autoincrement
 
Ultima modifica:

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
4^ prova effettuata con questa query:
vedi quanto detto per la prova3, poi se puoi posta la query definitiva

ps, nei miei sviluppi le query sono sempre complete, lista delle colonne e conseguenti valori, vedi suggerimento prova 1
in questo modo, se qualcuno facesse variazioni al db, che dovesso renderlo incongruente rispetto all'applicazione,
verrebbe segnalato un errore nell'esecuzione della query
sono contrario a creare automatismi per associare dati a colonne,
solito esempio estremo,
se dalla tabella fatture venisse eliminata la colonna iva, per sbaglio, l'automatismo garantirebbe il funzionamento dell'applicazione,
ma sai cosa significa perdere la colonna iva, senza che nessuno se ne accorge?

quindi sviluppa in modo "sicuro", garantendo sempre il risultato ….
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
da buon ultimo,
mi sono creato miei metodi "estendendo" la classe PDO
preferisco usare il posizionale "?" invece dell'associazione come fai tu
questa è uno dei miei metodi,
PHP:
  private function BindParams($sql, $params)
  {
    if($this->AllowLog) $this->MyLog($this->pdoSqlDebug($sql, $params));

    if (substr_count($sql, "?") != count($params))
      $this->MyErr("PDO : incongruenza nei parametri della query -> ".$sql);

    $params = $this->FixSQL($params);

    try { $sth = $this->pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
          $sth->execute($params);
          return $sth; }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e, $params); }
  }

quando le tue query funzionano, prova ad inserire come nome "D'Alessandro" e vedi che succede
poi pensa a "FixSQL" che leggi nel mio codice
 

macus_adi

Utente Attivo
5 Dic 2017
1.343
91
48
IT/SW
Per quanto riguarda la tipologia di dato appoggiati alla tabella information schema, senza andare lontano potresti utilizzare librerie di terze parti vedi medoo.in che ha tutti i metodi scritti abbastanza bene ampiamente documentato facilmente estensibile...
Giusto per conoscenza, potresti utilizzare Eloquent di Laravel, che di tutta la diatribia scritta non ne vedrai neanche l'ombra, una semplice Eloquent::Insert($dati);
;)
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
una semplice Eloquent::Insert($dati);
ma con pochi metodi ben scritti, estendendo la classe pdo, puoi ottenere lo stesso risultato, esempio
PHP:
public function queryM($sql, $params=array())  // return the number of the involved rows (insert, update, delete)
{
    return $this->BindParams($sql, $params)->rowCount();
}


$dbresult = $db->queryM($sql, array($car['cod'], $car['descr'], $car['um'], $car['sort'], $car['aggior'], $car['nr']));
ed hai "in mano" il tuo codice che rendi più funzionale alle tue necessità

eloquente, no ?
 
Ultima modifica:
Discussioni simili
Autore Titolo Forum Risposte Data
M [MySql - VB6 sp6] Problema connessione db con alcuni pc (errore Lost connection to MySQL server...). MySQL 1
M [MySQL] Solito errore #1064 con poca comprensione MySQL 14
C [MySQL] errore nell'importazione tabella con file csv MySQL 0
M errore lettura data nel mysql con funzione Where PHP 1
R Errore di comunicazione con database Mysql PHP 5
E errore php con database mysql PHP 0
G Errore connessione mysql con dreamweaver PHP 3
B Errore MySQL 10060 con mysql_connect PHP 1
Jensen Errore di sintassi con DELETE PHP 3
P errore 404 con javascript Javascript 2
R Navigare sito con cURL, mi restituisce errore PHP 0
L File CSV con app inventor da errore Sviluppo app per Android 2
I Errore 80040220 nella newsletter con paginazione Classic ASP 0
MarcoGrazia [PHP] Download di file con errore all'interno. PHP 1
Tommy03 Errore invio email con PHP PHP 1
Max 1 Errore driver con lettore di smart card Hardware 6
A [PHP] errore 404 e invio mai path pagina con link interrotto PHP 2
L [PHP] upload con errore PHP 2
auritidesign Errore con mysqli_fetch_array PHP 3
6 Errore pubblicazione sito con Muse Webdesign e Grafica 0
romeocharly errore del codice html con javascript durante ottimizzazione websitex5 Javascript 7
O errore INSERT con oggeto datetime MySQL 2
napuleone phpmyadmin problemi con windows 10 errore 200 PHP 0
C Errore con classe PHP 4
1 Errore di istallazione programma vb2010 con access in allegato MS Access 8
C Form con dentro div errore validatore w3c HTML e CSS 6
asevenx validazione W3C con errore utf-8 HTML e CSS 3
asevenx Errore di connessione e permessi in scrittura file .xml con Aruba Windows Hosting 8
M Errore ListView con ID "android.R.id.list" Sviluppo app per Android 1
J Problema con questo errore Error was: Undefined index: title linea 9 PHP 21
Z Errore con il register PHP 2
V problemi con lock tables (errore 1100) come fare? MySQL 0
A Errore con header ( Location...) PHP 4
F errore con wordpress plug in WordPress 0
valient13 Errore con le emotions [javascript + php] Javascript 0
F Errore configurazione APACHE con PHP Apache 1
neo996sps Errore con script per invio mail PHP 3
M errore in IE con array.style Javascript 0
E errore con internet explorer Windows e Software 2
A errore : "550 cannot stor no permission" per pubblicare il sito con expression web Webdesign e Grafica 0
A errore : "550 cannot stor no permission" per pubblicare il sito con expression web HTML e CSS 1
C Errore 678 con modem alice gate 2 plus wifi Reti LAN e Wireless 3
neo996sps Errore su connessione a DB con VB2008 express Visual Basic 1
asevenx errore con l'inserimento dei dati nel database, campi vuoti Classic ASP 1
G errore con div container HTML e CSS 1
neo996sps Errore visualizzazione sito con explorer HTML e CSS 1
asevenx errore durante l'invio di email con CDONTS Classic ASP 8
F Query con errore Database 3
wer16 errore in ie con float left HTML e CSS 2
Y strano errore con immissione nickname e password PHP 8

Discussioni simili