Prepared Statements - Wie verwenden?

Anmerkungen, Fragen und Hinweise zur Konfiguration dürfen in diesem Forum gepostet werden. // Notes, questions, and hints on the configuration can be posted here.
Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 13:53:00

Das kann ich noch gar nicht abschätzen.

Ich habe gestern erst mit der Umsetzung meiner Idee angefangen und gehe nun Schritt für Schritt vor. Dabei ergab sich bei der Registrierung das erste Problem hinsichtlich MySQLi.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 13:54:09

Ok, dann meld dich einfach wieder, wenn etwa snicht klappt. Wir finden da schon eine Lösung! 8-)

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 13:56:43

Kann ich natürlich machen.

Was jetzt noch fehlt (nachdem die insert_id geliefert wird), ist num_rows.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 14:11:45

Ok, machen wir daraus einen array:

einfach das return xyz mit dem folgenden ersetzen:

Code: Alles auswählen

return array($this->__lastInsertID, $this->__bindNumRows);
 
Erster Wert im Array ($data[0]) ist dann insert_id und zweiter Wert ($data[1]) ist num_rows.

Megger
Beiträge: 1233
Registriert: 04.11.2008, 10:57:37

Re: Prepared Statements - Wie verwenden?

Beitrag von Megger » 30.03.2011, 14:14:04

Mach besser ein

Code: Alles auswählen

return array('lastInsertID'=>$this->__lastInsertID, 'numRows'=>$this->__bindNumRows); 
daraus, so kannst du später per

Code: Alles auswählen

$data['lastInsertID'];
$data['numRows'];
 
darauf zugreifen und musst nicht mit Zahlen arbeiten
Tutorial: Browsergame mit dem APF (Die ersten Parts handeln von Installation und Inbetriebnahme des APFs, deswegen sicherlich auch für alle Nicht-Browsergame-Programmierer interessant)

APF-Version
  • Entwicklung: 2.0
  • Produktiv: 1.15

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 14:24:09

Schon umgesetzt. :) Das war dann allerdings noch das kleinere Problem.

Aber ich habe bereits das nächste, wenn ich mir z.B. alle Daten aus der Tabelle user holen möchte:

Code: Alles auswählen

$cM = &$this->__getServiceObject('core::database', 'ConnectionManager');
$SQL = &$cM->getConnection('MySQLi'); 
Variante 1

Code: Alles auswählen

$data = $SQL->executeTextBindStatement('SELECT * FROM user',''); 

Code: Alles auswählen

Exception-ID:  	45ddaefd66bf98d390ccb947b11fb2c2
Type: 	DatabaseHandlerException
Message: 	[MySQLiHandler->executeTextBindStatement()] Number of given params (1) does not match number of bind params within the statement (0)! Current statement: SELECT * FROM user
Number: 	256
File: 	/var/www/apf1/apps/core/database/MySQLiHandler.php
Line: 	292
Logischerweise. Denke da braucht man nicht zu diskutieren, wieso das nicht läuft.

Variante 2

Code: Alles auswählen

$value = array();
$data = $SQL->executeTextBindStatement('SELECT * FROM user', $value); 

Code: Alles auswählen

Error-ID:  	ff1f2a1d6c008cf8932ee956a5bf67c8
Message: 	Wrong parameter count for mysqli_stmt::bind_param()
Number: 	2
File: 	/var/www/apf1/apps/core/database/MySQLiHandler.php
Line: 	377
Erscheint mir auch nachvollziehbar...

Variante 3

Code: Alles auswählen

$value = array('');
$data = $SQL->executeTextBindStatement('SELECT * FROM user', $value);  

Code: Alles auswählen

Exception-ID:  	45ddaefd66bf98d390ccb947b11fb2c2
Type: 	DatabaseHandlerException
Message: 	[MySQLiHandler->executeTextBindStatement()] Number of given params (1) does not match number of bind params within the statement (0)! Current statement: SELECT * FROM user
Number: 	256
File: 	/var/www/apf1/apps/core/database/MySQLiHandler.php
Line: 	292
Wie kann ich also alle Datensätze einer Tabelle holen? Welchen Paramter soll ich hierzu an executeTextBindStatement übergeben? Vielleicht stehe ich einfach nur auf dem Schlauch...

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 15:05:26

Versuch mal anstatt des * bei deiner Abfrage direkt die Spalten der Tebelle anzugeben. Und genau die packst du dann auch nochmal in das Array $value. Mal schauen, was passiert ;).

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von Screeze » 30.03.2011, 15:21:47

dave hat geschrieben:Versuch mal anstatt des * bei deiner Abfrage direkt die Spalten der Tebelle anzugeben. Und genau die packst du dann auch nochmal in das Array $value. Mal schauen, was passiert ;).
Nene das ist nicht das Problem, er darf blos kein 2. argument übergeben.
Wenn du dir die Methodendefiniton mal anschaust, dann ist der 2. parameter optional, d.h. du brauchst ihn nicht übergeben. Ein STRING (auch wenn er leer ist) ist aber nicht NICHTS sondern eben ein string.

Code: Alles auswählen

public function executeTextBindStatement($statement,$params = array(),$logStatement = false){
Alternativ, wenn du mal den 3. parameter brauchst, übergibst du den standartwert, nämlich ein ein leeres array().

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 15:29:15

Das war anfangs auch meine Vermutung. Nur als ich mir dann nochmal Teil angesehen habe, wobei die Exception geworfen wird, bin ich stutzig geworden.

Woran erkennst du, dass der 2. Parameter optional ist?

Code: Alles auswählen

public function executeTextBindStatement($statement,$params = array(),$logStatement = false)
 
Wird das anhand der "Vorbelegung" ($params = array()) geregelt?

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von Screeze » 30.03.2011, 15:31:00

Korrekt, hat ein Parameter eine vorbelegung, muss er nicht übergeben werden.

Es wäre also folgendes alles korrekt:

Code: Alles auswählen

executeTextBindStatement($statement);
executeTextBindStatement($statement, array());
executeTextBindStatement($statement, array(),true);
 

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 15:36:22

Jup, verstanden, sauber! :geek:

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 16:59:14

Bin zwar eben erst aus dem Mittagsschlaf erwacht, bin deshalb noch nicht ganz wach und habe vielleicht etwas überlesen, aber folgendes

Code: Alles auswählen

$data = $SQL->executeTextBindStatement('SELECT * FROM user'); 
führt zu diese Fehlermeldung

Code: Alles auswählen

Error-ID:  	ff1f2a1d6c008cf8932ee956a5bf67c8
Message: 	Wrong parameter count for mysqli_stmt::bind_param()
Number: 	2
File: 	/var/www/apf1/apps/core/database/MySQLiHandler.php
Line: 	377
Also leider keine Lösung...

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von Screeze » 30.03.2011, 17:02:41

Dann ist das definitiv ein Bug des MySQLiHandlers, aber das muss sich besser Christian ansehen, da muss ich ausnahmsweise passen :?

solange könntest du aber denke ich ohne das BIND arbeiten und nur executeTextStatement() verwenden solange du keine Variablen Daten brauchst.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 17:19:13

Jup, scheint ein Bug zu sein. Habe das nochmal etwas anlysiert ;).

Beim Aufruf der bindParams ist der zweite Parameter $params schon nicht mehr als optional angegeben. Jedoch wird dieser über die executeTextBindStatement übergeben, wo er ja noch optional ist. Foglich drehen wir uns im Kreis bzw. das bindParams arbeitet nicht und gibt uns den Fehler.

Ne Lösung habe ich auch nicht. Einzig du könntest probieren, wirklich alle Parameter (Spaltennamen deiner Tabelle) zu übergeben, was aber in Arbeit ausarten könnte.

Megger
Beiträge: 1233
Registriert: 04.11.2008, 10:57:37

Re: Prepared Statements - Wie verwenden?

Beitrag von Megger » 30.03.2011, 17:34:12

Aber $params ist innerhalb von executeTextBindStatement ein leeres Array wenn nichts übergeben wurde (da es ja eine Standardbelegung hat), deswegen kann es auch bei bindParams erforderlich sein und muss nicht optional sein.

Das Problem ist das call_user_func_array innerhalb des bindParams

Edit:
Ist es denn richtig, dass man bei MySQLi beim bindParam ein leeres Array übergibt, wenn man nichts zum binden hat? Habe bisher noch nicht mit PreparedStatements gearbeitet
Tutorial: Browsergame mit dem APF (Die ersten Parts handeln von Installation und Inbetriebnahme des APFs, deswegen sicherlich auch für alle Nicht-Browsergame-Programmierer interessant)

APF-Version
  • Entwicklung: 2.0
  • Produktiv: 1.15

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast