Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.php > #3542 > unrolled thread

Problem mit PDO

Started byPeter Müller <peter.mueller@c-major.de>
First post2015-11-14 20:54 +0100
Last post2015-11-20 21:59 +0100
Articles 20 on this page of 22 — 6 participants

Back to article view | Back to de.comp.lang.php


Contents

  Problem mit PDO Peter Müller <peter.mueller@c-major.de> - 2015-11-14 20:54 +0100
    Re: Problem mit PDO Arno Welzel <usenet@arnowelzel.de> - 2015-11-14 21:32 +0100
      Re: Problem mit PDO Peter Müller <peter.mueller@c-major.de> - 2015-11-14 22:19 +0100
        Re: Problem mit PDO Markus Grob <snoopy@ilnet.ch> - 2015-11-14 23:41 +0100
          Re: Problem mit PDO Peter Müller <peter.mueller@c-major.de> - 2015-11-15 10:25 +0100
            Re: Problem mit PDO Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2015-11-15 12:42 +0100
            Re: Problem mit PDO Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2015-11-15 13:03 +0100
              Re: Problem mit PDO Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-15 14:26 +0100
                Re: Problem mit PDO Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2015-11-15 16:32 +0100
              Re: Problem mit PDO Peter Müller <peter.mueller@c-major.de> - 2015-11-15 14:37 +0100
                Re: Problem mit PDO Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-15 15:30 +0100
                  Re: Problem mit PDO Peter Müller <peter.mueller@c-major.de> - 2015-11-15 19:26 +0100
                    Re: Problem mit PDO Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-15 21:10 +0100
            Re: Problem mit PDO Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-15 14:23 +0100
              Re: Problem mit PDO Peter Müller <peter.mueller@c-major.de> - 2015-11-15 14:39 +0100
        Re: Problem mit PDO Arno Welzel <usenet@arnowelzel.de> - 2015-11-16 08:43 +0100
          Re: Problem mit PDO Peter Müller <peter.mueller@c-major.de> - 2015-11-16 21:23 +0100
      Re: Problem mit PDO Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2015-11-15 13:09 +0100
        Re: Problem mit PDO Markus Grob <snoopy@ilnet.ch> - 2015-11-17 09:48 +0100
          Re: Problem mit PDO Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-11-17 20:13 +0100
            Re: Problem mit PDO Stefan+Usenet@Froehlich.Priv.at (Stefan Froehlich) - 2015-11-17 22:09 +0000
            Re: Problem mit PDO Markus Grob <snoopy@ilnet.ch> - 2015-11-20 21:59 +0100

Page 1 of 2  [1] 2  Next page →


#3542 — Problem mit PDO

FromPeter Müller <peter.mueller@c-major.de>
Date2015-11-14 20:54 +0100
SubjectProblem mit PDO
Message-ID<n283h2$e0d$1@news.albasani.net>
Hallo,

ich arbeite mich gerade mit PDO ein und komme an einem Punkt nicht
weiter, ich hoffe ihr könnt mir helfen. Es geht um die Umsetzung dieser
SQL-Abfrage:
mysql> SELECT min(jahr) as minjahr
    -> FROM wiealt
    -> WHERE baldwin > 100000;
+---------+
| minjahr |
+---------+
|    1950 |
+---------+
1 row in set (0.00 sec)

Mein (reduziertes) PDO-Codeschnipsel sieht so aus:

$firma = 'baldwin';
$nummer = 100000;
$query2 = "
	SELECT min(jahr) as minjahr
	FROM wiealt
	WHERE :firma > :nummer";
$stmt = $dbmerz -> prepare($query2);
$stmt -> bindValue(':firma', $firma, PDO::PARAM_STR);
$stmt -> bindValue(':nummer', $nummer, PDO::PARAM_INT);
$stmt -> execute();
$result2 = $stmt->fetchAll(PDO::FETCH_OBJ);
if($result2)
	{
	$max=$result2[0]->minjahr;
	var_dump($result2);
}
print "<p>Max = $max.</p>";

Die unerwartete Ausgabe:
array(1) { [0]=> object(stdClass)#86 (1) { ["minjahr"]=> NULL } }
Notice: Undefined variable: min in
/var/www/html/merz-klaviere.de/service/wie_alt.php on line 180

Max = .

Kann mir hier jemand weiterhelfen?

Viele Grüße,

Peter

[toc] | [next] | [standalone]


#3544

FromArno Welzel <usenet@arnowelzel.de>
Date2015-11-14 21:32 +0100
Message-ID<56479A45.3090901@arnowelzel.de>
In reply to#3542
Peter Müller schrieb am 2015-11-14 um 20:54:

> Hallo,
> 
> ich arbeite mich gerade mit PDO ein und komme an einem Punkt nicht
> weiter, ich hoffe ihr könnt mir helfen. Es geht um die Umsetzung dieser
> SQL-Abfrage:
> mysql> SELECT min(jahr) as minjahr
>     -> FROM wiealt
>     -> WHERE baldwin > 100000;
> +---------+
> | minjahr |
> +---------+
> |    1950 |
> +---------+
> 1 row in set (0.00 sec)
> 
> Mein (reduziertes) PDO-Codeschnipsel sieht so aus:
> 
> $firma = 'baldwin';
> $nummer = 100000;
> $query2 = "
> 	SELECT min(jahr) as minjahr
> 	FROM wiealt
> 	WHERE :firma > :nummer";

Wieso nicht in einer Zeile? Eine Aufteilung auf mehrere Zeilen sollte
auch eher so aussehen:

$query2 = "SELECT min(jahr) as minjahr ".
          "FROM wiealt ".
          "WHERE :firma > :nummer";

Siehe auch <http://php.net/manual/de/language.types.string.php>

> $stmt = $dbmerz -> prepare($query2);
> $stmt -> bindValue(':firma', $firma, PDO::PARAM_STR);
> $stmt -> bindValue(':nummer', $nummer, PDO::PARAM_INT);
> $stmt -> execute();
> $result2 = $stmt->fetchAll(PDO::FETCH_OBJ);
> if($result2)
> 	{
> 	$max=$result2[0]->minjahr;
> 	var_dump($result2);
> }
> print "<p>Max = $max.</p>";
> 
> Die unerwartete Ausgabe:
> array(1) { [0]=> object(stdClass)#86 (1) { ["minjahr"]=> NULL } }
> Notice: Undefined variable: min in
> /var/www/html/merz-klaviere.de/service/wie_alt.php on line 180

Welche Zeile ist 180 in dem obigen Beispiel?



-- 
Arno Welzel
http://arnowelzel.de
http://de-rec-fahrrad.de
http://fahrradzukunft.de

[toc] | [prev] | [next] | [standalone]


#3545

FromPeter Müller <peter.mueller@c-major.de>
Date2015-11-14 22:19 +0100
Message-ID<n288g5$n4i$1@news.albasani.net>
In reply to#3544
Arno Welzel schrieb am 14.11.2015 um 21:32:
> Peter Müller schrieb am 2015-11-14 um 20:54:
> 
>> Hallo,
>>
>> ich arbeite mich gerade mit PDO ein und komme an einem Punkt nicht
>> weiter, ich hoffe ihr könnt mir helfen. Es geht um die Umsetzung dieser
>> SQL-Abfrage:
>> mysql> SELECT min(jahr) as minjahr
>>     -> FROM wiealt
>>     -> WHERE baldwin > 100000;
>> +---------+
>> | minjahr |
>> +---------+
>> |    1950 |
>> +---------+
>> 1 row in set (0.00 sec)
>>
>> Mein (reduziertes) PDO-Codeschnipsel sieht so aus:
>>
>> $firma = 'baldwin';
>> $nummer = 100000;
>> $query2 = "
>> 	SELECT min(jahr) as minjahr
>> 	FROM wiealt
>> 	WHERE :firma > :nummer";
> 
> Wieso nicht in einer Zeile? Eine Aufteilung auf mehrere Zeilen sollte
> auch eher so aussehen:
> 
> $query2 = "SELECT min(jahr) as minjahr ".
>           "FROM wiealt ".
>           "WHERE :firma > :nummer";

Ist nur übersichtlicher. Es erscheint auch keine notice deswegen, aber
ich kann's natürlich gerne mal mit einer einzeiligen query testen.

> 
> Siehe auch <http://php.net/manual/de/language.types.string.php>
> 
>> $stmt = $dbmerz -> prepare($query2);
>> $stmt -> bindValue(':firma', $firma, PDO::PARAM_STR);
>> $stmt -> bindValue(':nummer', $nummer, PDO::PARAM_INT);
>> $stmt -> execute();
>> $result2 = $stmt->fetchAll(PDO::FETCH_OBJ);
>> if($result2)
>> 	{
>> 	$max=$result2[0]->minjahr;
>> 	var_dump($result2);
>> }
>> print "<p>Max = $max.</p>";
>>
>> Die unerwartete Ausgabe:
>> array(1) { [0]=> object(stdClass)#86 (1) { ["minjahr"]=> NULL } }
>> Notice: Undefined variable: min in
>> /var/www/html/merz-klaviere.de/service/wie_alt.php on line 180
> 
> Welche Zeile ist 180 in dem obigen Beispiel?

Es geht nicht um die Notice: Undefined variable (...) , die tritt nur
auf durch die Reduzierung des Codes. Es geht um das falsche SQL-Ergebnis
'NULL' statt '1950', das ist mir nicht klar. var_dump des Original-Codes
liefert
array(1) { [0]=> object(stdClass)#86 (1) { ["maxjahr"]=> string(4)
"2100" } } array(1) { [0]=> object(stdClass)#87 (1) { ["minjahr"]=> NULL } }

, das sind beides die Extremwerte der Tabelle.

[toc] | [prev] | [next] | [standalone]


#3546

FromMarkus Grob <snoopy@ilnet.ch>
Date2015-11-14 23:41 +0100
Message-ID<n28d72$dge$1@dont-email.me>
In reply to#3545
Peter Müller schrieb:
> Arno Welzel schrieb am 14.11.2015 um 21:32:
>> Peter Müller schrieb am 2015-11-14 um 20:54:
>>
>>> Hallo,
>>>
>>> ich arbeite mich gerade mit PDO ein und komme an einem Punkt nicht
>>> weiter, ich hoffe ihr könnt mir helfen. Es geht um die Umsetzung dieser
>>> SQL-Abfrage:
>>> mysql> SELECT min(jahr) as minjahr
>>>      -> FROM wiealt
>>>      -> WHERE baldwin > 100000;
>>> +---------+
>>> | minjahr |
>>> +---------+
>>> |    1950 |
>>> +---------+
>>> 1 row in set (0.00 sec)
>>>
>>> Mein (reduziertes) PDO-Codeschnipsel sieht so aus:
>>>
>>> $firma = 'baldwin';
>>> $nummer = 100000;
>>> $query2 = "
>>> 	SELECT min(jahr) as minjahr
>>> 	FROM wiealt
>>> 	WHERE :firma > :nummer";
>>
>> Wieso nicht in einer Zeile? Eine Aufteilung auf mehrere Zeilen sollte
>> auch eher so aussehen:
>>
>> $query2 = "SELECT min(jahr) as minjahr ".
>>            "FROM wiealt ".
>>            "WHERE :firma > :nummer";
>
> Ist nur übersichtlicher. Es erscheint auch keine notice deswegen, aber
> ich kann's natürlich gerne mal mit einer einzeiligen query testen.

Er meinte sicher, dass Du das SELECT auf die gleiche Zeile schreiben 
sollst wie $query2


>>> Die unerwartete Ausgabe:
>>> array(1) { [0]=> object(stdClass)#86 (1) { ["minjahr"]=> NULL } }
>>> Notice: Undefined variable: min in
>>> /var/www/html/merz-klaviere.de/service/wie_alt.php on line 180
>>
>> Welche Zeile ist 180 in dem obigen Beispiel?

Das ist sicher die Zeile mit dem SELECT, richtig? Irgendwie kommt das 
pdo mit Deinem min nicht klar. Da ich pdo nicht anwende, weiss ich 
nicht, ob Du diese Abfrage hier noch anpassen musst.


> Es geht nicht um die Notice: Undefined variable (...) , die tritt nur
> auf durch die Reduzierung des Codes. Es geht um das falsche SQL-Ergebnis
> 'NULL' statt '1950', das ist mir nicht klar. var_dump des Original-Codes
> liefert
> array(1) { [0]=> object(stdClass)#86 (1) { ["maxjahr"]=> string(4)
> "2100" } } array(1) { [0]=> object(stdClass)#87 (1) { ["minjahr"]=> NULL } }
>
> , das sind beides die Extremwerte der Tabelle.

Doch, das sind beides wichtige Werte. minjahr ist NULL, weil min als 
nicht definierte Variable angeschaut wird, anstatt als SQL-Funktion. 
Würdest Du hier das min weglassen und umstellen auf:

SELECT jahr....
WHERE jahr = '1950'

Würde das funktionieren, doch es ist nicht Ziel des Codes :-)

Wie erwähnt, ich kenne pdo nicht, doch kläre ab, ob das Ganze noch 
angepasst werden muss mit SELECT min(x)

Gruss, Markus

[toc] | [prev] | [next] | [standalone]


#3547

FromPeter Müller <peter.mueller@c-major.de>
Date2015-11-15 10:25 +0100
Message-ID<n29j1k$705$1@news.albasani.net>
In reply to#3546
Hallo,

danke an Euch, Arno und Markus. Ich habe nochmal alles von vorne
getestet mit dieser table und diesem php:

CREATE TABLE wiealt2 (
	`id` int(11) NOT NULL,
	`jahr` smallint(5) unsigned DEFAULT NULL,
	`baldwin` int(10) unsigned DEFAULT NULL)
	ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `wiealt2` (`id`, `jahr`, `baldwin`) VALUES
(1, 1700, NULL),
(10, 1810, 11),
(11, 1811, 12),
(12, 1812, 13),
(13, 1813, 14),
(14, 1814, 15),
(15, 1815, 16),
(16, 1816, 17),
(17, 1817, 18),
(18, 1818, 19),
(19, 1819, NULL),
(99, 1899, NULL);

$firma = 'baldwin';
$nummer = '15';

$query1 = "SELECT max(jahr) as maxjahr FROM wiealt2 WHERE :firma <=
:nummer";
$stmt = $dbmerz -> prepare($query1);
$stmt -> bindValue(':firma', $firma, PDO::PARAM_STR);
$stmt -> bindValue(':nummer', $nummer, PDO::PARAM_INT);
$stmt -> execute();
$result1 = $stmt->fetchAll(PDO::FETCH_OBJ);
if($result1)
	{
	$min=$result1[0]->maxjahr;
	var_dump($result1);
}
$query2 = "SELECT min(jahr) as minjahr FROM wiealt2 WHERE :firma > :nummer";
$stmt = $dbmerz -> prepare($query2);
$stmt -> bindValue(':firma', $firma, PDO::PARAM_STR);
$stmt -> bindValue(':nummer', $nummer, PDO::PARAM_INT);
$stmt -> execute();
$result2 = $stmt->fetchAll(PDO::FETCH_OBJ);
if($result2)
	{
	$max=$result2[0]->minjahr;
	var_dump($result2);
}
print "<p>Nummer = $nummer; Firma = $firma; Min = $min, Max = $max.</p>";

Ausgabe: array(1) { [0]=> object(stdClass)#86 (1) { ["maxjahr"]=> NULL }
} array(1) { [0]=> object(stdClass)#87 (1) { ["minjahr"]=> string(4)
"1700" } }

Nummer = 15; Firma = baldwin; Min = , Max = 1700.

SQL-Ausgabe ist aber dagegen:
mysql> SELECT max(jahr) as maxjahr FROM wiealt2 WHERE baldwin <= 15;
+---------+
| maxjahr |
+---------+
|    1814 |
+---------+
1 row in set (0.01 sec)
mysql> SELECT min(jahr) as minjahr FROM wiealt2 WHERE baldwin > 15;
+---------+
| minjahr |
+---------+
|    1815 |
+---------+
1 row in set (0.00 sec)

Der PHP-Code liefert also NULL, 1700, SQL liefert 1814,1815 auf dieselbe
Abfrage. Mir scheint, die WHERE-Abfrage wird hier verworfen. Wieso?

Viele Grüße,

Peter

[toc] | [prev] | [next] | [standalone]


#3548

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2015-11-15 12:42 +0100
Message-ID<n29r2e$m7n$1@news.albasani.net>
In reply to#3547
On 15/11/15 10:25, Peter Müller wrote:
> INSERT INTO `wiealt2` (`id`, `jahr`, `baldwin`) [...]
>
> $firma = 'baldwin';
> $nummer = '15';
>
> $query1 = "SELECT max(jahr) as maxjahr FROM wiealt2 WHERE :firma <=
> :nummer";

     WHERE :firma <= :nummer --> WHERE 'baldwin' <= 15

Hier wird also 'baldwin' als String*wert* behandelt. Es ist aber 
offensichtlich ein *Spaltenname* gemeint, also

     WHERE baldwin <= 15

Und einen Spaltennamen kannst Du *so* (Parameter :firma) eben *nicht* 
angeben.

Gruß,
Thomas

-- 
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)

[toc] | [prev] | [next] | [standalone]


#3549

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2015-11-15 13:03 +0100
Message-ID<n29s9o$ok1$1@news.albasani.net>
In reply to#3547
On 15/11/15 10:25, Peter Müller wrote:
> INSERT INTO `wiealt2` (`id`, `jahr`, `baldwin`) VALUES [...]
>
> $firma = 'baldwin';
> $nummer = '15';

> $query2 = "SELECT min(jahr) as minjahr FROM wiealt2 WHERE :firma > :nummer";
 > SELECT min(jahr) as minjahr FROM wiealt2 WHERE baldwin > 15;

> Der PHP-Code liefert also NULL, 1700, SQL liefert 1814,1815 auf dieselbe
> Abfrage.

Es ist eben nicht dieselbe Abfrage. In $query2 vergleichst Du den 
*String* 'baldwin' mit der Zahl 15, in der Konsole den Wert der *Spalte* 
`baldwin` mit der Zahl 15.

> Mir scheint, die WHERE-Abfrage wird hier verworfen. Wieso?

mysql> select 'baldwin' <= 15;
+-----------------+
| 'baldwin' <= 15 |
+-----------------+
|               1 |
+-----------------+
1 row in set, 1 warning (0.00 sec)

Die Bedingung ist immer wahr, also werden *alle* Einträge berücksichtigt 
-- und das "niedrigste" Jahr ist 1700.

mysql> select 'baldwin' > 15;
+----------------+
| 'baldwin' > 15 |
+----------------+
|              0 |
+----------------+
1 row in set, 1 warning (0.00 sec)

Die Bedingung ist immer falsch, folglich wird kein einziger Eintrag 
berücksichtigt und das Ergebnis ist NULL.

Der Vollständigkeit halber:

mysql> show warnings;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'baldwin' |
+---------+------+---------------------------------------------+
1 row in set (0.00 sec)


Gruß,
Thomas

-- 
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)

[toc] | [prev] | [next] | [standalone]


#3552

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-11-15 14:26 +0100
Message-ID<2832576.C0p1vsflBy@PointedEars.de>
In reply to#3549
Thomas Mlynarczyk wrote:

> mysql> select 'baldwin' <= 15;
> +-----------------+
> | 'baldwin' <= 15 |
> +-----------------+
> |               1 |
> […]
> Die Bedingung ist immer wahr, also werden *alle* Einträge berücksichtigt
> -- und das "niedrigste" Jahr ist 1700.
> 
> mysql> select 'baldwin' > 15;
> +----------------+
> | 'baldwin' > 15 |
> […]
> Die Bedingung ist immer falsch, folglich wird kein einziger Eintrag
> berücksichtigt und das Ergebnis ist NULL.

Jedoch wird gemäss OP für MAX(jahr) und :firma <= :number angeblich NULL und 
für MIN(jahr) und :firma > :number angeblich 1700 geliefert.

Ich kann das bei meinen Tests nicht nachvollziehen – erhalte wie erwartet 
1899 und NULL –, vermute daher Schludrigkeit des OPs.
 
> mysql> show warnings;
> +---------+------+---------------------------------------------+
> | Level   | Code | Message                                     |
> +---------+------+---------------------------------------------+
> | Warning | 1292 | Truncated incorrect DOUBLE value: 'baldwin' |
> […]

ACK, *das* erhalte ich auch.

ObPHP:

  $db = PDO("mysql:…", …);
  …
  var_dump($db->query("SHOW WARNINGS")->fetchAll());

-- 
PointedEars
Zend Certified PHP Engineer
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#3557

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2015-11-15 16:32 +0100
Message-ID<n2a8im$gvr$1@news.albasani.net>
In reply to#3552
On 15/11/15 14:26, Thomas 'PointedEars' Lahn wrote:
> Thomas Mlynarczyk wrote:
>
>> mysql> select 'baldwin' <= 15;
>> +-----------------+
>> | 'baldwin' <= 15 |
>> +-----------------+
>> |               1 |
>> […]
>> Die Bedingung ist immer wahr, also werden *alle* Einträge berücksichtigt
>> -- und das "niedrigste" Jahr ist 1700.

Korrektur: bei dieser Bedingung, die zu der MAX()-Query gehört, müßte 
das *höchste* Jahr (1899) zurückgeliefert werden.

> Jedoch wird gemäss OP für MAX(jahr) und :firma <= :number angeblich NULL und
> für MIN(jahr) und :firma > :number angeblich 1700 geliefert.
>
> Ich kann das bei meinen Tests nicht nachvollziehen – erhalte wie erwartet
> 1899 und NULL –, vermute daher Schludrigkeit des OPs.

Hast recht -- ich hatte bei den beiden Queries gedanklich min() und 
max() vertauscht.

Gruß,
Thomas

-- 
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)

[toc] | [prev] | [next] | [standalone]


#3553

FromPeter Müller <peter.mueller@c-major.de>
Date2015-11-15 14:37 +0100
Message-ID<n2a1ql$3a3$1@news.albasani.net>
In reply to#3549
Thomas Mlynarczyk schrieb am 15.11.2015 um 13:03:
> On 15/11/15 10:25, Peter Müller wrote:
>> INSERT INTO `wiealt2` (`id`, `jahr`, `baldwin`) VALUES [...]
>>
>> $firma = 'baldwin';
>> $nummer = '15';
> 
>> $query2 = "SELECT min(jahr) as minjahr FROM wiealt2 WHERE :firma >
>> :nummer";
>> SELECT min(jahr) as minjahr FROM wiealt2 WHERE baldwin > 15;
> 
>> Der PHP-Code liefert also NULL, 1700, SQL liefert 1814,1815 auf dieselbe
>> Abfrage.
> 
> Es ist eben nicht dieselbe Abfrage. In $query2 vergleichst Du den
> *String* 'baldwin' mit der Zahl 15, in der Konsole den Wert der *Spalte*
> `baldwin` mit der Zahl 15.

Das ist das, was ich übersehen hatte. Danke! Da die Arbeit mit den
PDO-Klassen neu für mich ist, hatte ich noch nicht
PDOStatement::bindColumn entdeckt. Das löst das Problem. Ich hatte die
Spaltennamen wie Strings behandelt.

viele Grüße,

Peter

[toc] | [prev] | [next] | [standalone]


#3556

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-11-15 15:30 +0100
Message-ID<2514085.4R5y6r8EeQ@PointedEars.de>
In reply to#3553
Peter Müller wrote:

> Thomas Mlynarczyk schrieb am 15.11.2015 um 13:03:
>> On 15/11/15 10:25, Peter Müller wrote:
>>> INSERT INTO `wiealt2` (`id`, `jahr`, `baldwin`) VALUES [...]
>>>
>>> $firma = 'baldwin';
>>> $nummer = '15';
>> 
>>> $query2 = "SELECT min(jahr) as minjahr FROM wiealt2 WHERE :firma >
>>> :nummer";
>>> SELECT min(jahr) as minjahr FROM wiealt2 WHERE baldwin > 15;
>> 
>>> Der PHP-Code liefert also NULL, 1700, SQL liefert 1814,1815 auf dieselbe
>>> Abfrage.
>> 
>> Es ist eben nicht dieselbe Abfrage. In $query2 vergleichst Du den
>> *String* 'baldwin' mit der Zahl 15, in der Konsole den Wert der *Spalte*
>> `baldwin` mit der Zahl 15.
> 
> Das ist das, was ich übersehen hatte. Danke! Da die Arbeit mit den
> PDO-Klassen neu für mich ist, hatte ich noch nicht
> PDOStatement::bindColumn entdeckt. Das löst das Problem. Ich hatte die
> Spaltennamen wie Strings behandelt.

PDOStatement::bindColumn() tut nicht das, was Du anscheinend annimmst: Damit 
wird _nicht_ der Wert einer Variablen als *Name* einer Spalte in einem 
Prepared Statement verwendet.  

Stattdessen wird damit der Wert einer Variablen an den *Wert* eines *Feldes* 
eines *Ergebnisdatensatzes* gebunden, wenn man PDOStatement::fetch() oder 
PDOStatement::fetchAll() verwendet.

RTFM: <http://php.net/manual/en/pdostatement.bindcolumn.php>

Ausserdem schrieb ich bereits, dass Deine Datenbank wahrscheinlich falsch 
strukturiert ist, wenn Du variable Spaltennamen in Abfragen verwenden musst.

-- 
PointedEars
Zend Certified PHP Engineer
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#3558

FromPeter Müller <peter.mueller@c-major.de>
Date2015-11-15 19:26 +0100
Message-ID<n2aint$78q$1@news.albasani.net>
In reply to#3556
Thomas 'PointedEars' Lahn schrieb am 15.11.2015 um 15:30:
> Peter Müller wrote:
> 
>> Thomas Mlynarczyk schrieb am 15.11.2015 um 13:03:
>>> On 15/11/15 10:25, Peter Müller wrote:
>>>> INSERT INTO `wiealt2` (`id`, `jahr`, `baldwin`) VALUES [...]
>>>>
>>>> $firma = 'baldwin';
>>>> $nummer = '15';
>>>
>>>> $query2 = "SELECT min(jahr) as minjahr FROM wiealt2 WHERE :firma >
>>>> :nummer";
>>>> SELECT min(jahr) as minjahr FROM wiealt2 WHERE baldwin > 15;
>>>
>>>> Der PHP-Code liefert also NULL, 1700, SQL liefert 1814,1815 auf dieselbe
>>>> Abfrage.
>>>
>>> Es ist eben nicht dieselbe Abfrage. In $query2 vergleichst Du den
>>> *String* 'baldwin' mit der Zahl 15, in der Konsole den Wert der *Spalte*
>>> `baldwin` mit der Zahl 15.
>>
>> Das ist das, was ich übersehen hatte. Danke! Da die Arbeit mit den
>> PDO-Klassen neu für mich ist, hatte ich noch nicht
>> PDOStatement::bindColumn entdeckt. Das löst das Problem. Ich hatte die
>> Spaltennamen wie Strings behandelt.
> 
> PDOStatement::bindColumn() tut nicht das, was Du anscheinend annimmst: Damit 
> wird _nicht_ der Wert einer Variablen als *Name* einer Spalte in einem 
> Prepared Statement verwendet.  

Das dachte ich in der Tat. Gibt es denn überhaupt diese Möglichkeit?
Sonst müsste ich, siehe unten, die DB ändern.

> Stattdessen wird damit der Wert einer Variablen an den *Wert* eines *Feldes* 
> eines *Ergebnisdatensatzes* gebunden, wenn man PDOStatement::fetch() oder 
> PDOStatement::fetchAll() verwendet.

> RTFM: <http://php.net/manual/en/pdostatement.bindcolumn.php>

Ich kauf mirn Buch. Kein Scherz.


> Ausserdem schrieb ich bereits, dass Deine Datenbank wahrscheinlich falsch 
> strukturiert ist, wenn Du variable Spaltennamen in Abfragen verwenden musst.

Das würde hier zu weit führen.

Viele Grüße,

Peter

[toc] | [prev] | [next] | [standalone]


#3559

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-11-15 21:10 +0100
Message-ID<1738922.5VfiKhCZny@PointedEars.de>
In reply to#3558
Peter Müller wrote:

> Thomas 'PointedEars' Lahn schrieb am 15.11.2015 um 15:30:
>> Peter Müller wrote:
>>> Thomas Mlynarczyk schrieb am 15.11.2015 um 13:03:
>>>> Es ist eben nicht dieselbe Abfrage. In $query2 vergleichst Du den
>>>> *String* 'baldwin' mit der Zahl 15, in der Konsole den Wert der
>>>> *Spalte* `baldwin` mit der Zahl 15.
>>>
>>> Das ist das, was ich übersehen hatte. Danke! Da die Arbeit mit den
>>> PDO-Klassen neu für mich ist, hatte ich noch nicht
>>> PDOStatement::bindColumn entdeckt. Das löst das Problem. Ich hatte die
>>> Spaltennamen wie Strings behandelt.
>> 
>> PDOStatement::bindColumn() tut nicht das, was Du anscheinend annimmst:
>> Damit wird _nicht_ der Wert einer Variablen als *Name* einer Spalte in
>> einem Prepared Statement verwendet.
> 
> Das dachte ich in der Tat. Gibt es denn überhaupt diese Möglichkeit?

Ja; zwei Möglichkeiten dafür habe ich beschrieben.

Eine dritte Möglichkeit, die ebenfalls durch eine Datenbank-Klasse abgedeckt 
werden kann (und in meiner Klasse wird), sind durch Anführungszeichen 
begrenzte Zeichenfolgen-Literale (“double-quoted strings”), innerhalb denen 
bei PHP Variableninterpolation stattfinden kann:

<http://php.net/manual/en/language.types.string.php#language.types.string.syntax.double>

Auch da sollte der Spaltenname aber mindestens mit den Mitteln der 
verwendeten Datenbanksprache gequotet werden.  Dies bei Namen, die nicht 
benutzerinjiziert sind, vor allem, damit diese bei Beachtung der Empfehlung, 
dass sie international verständlich, mithin auf Englisch, sein sollten, 
möglichst unabhängig von der Version der Datenbanksprache nicht als 
Schlüsselwörter fehlinterpretiert werden können.  (In der Regel stellt sich 
diese Problematik, wenn überhaupt, jedoch nur für solche Namen, denn die 
Datenbankstruktur sollte für den Benutzer der Applikation nicht direkt 
ersichtlich sein.  Öffentliche Namen sind applikationsintern auf intern 
verwendete zu mappen, um die Darstellung von der Speicherung zu entkoppeln 
und möglichst wenig Möglichkeiten für Angriffe zu bieten.)

> Sonst müsste ich, siehe unten, die DB ändern.

Basierend auf den vorliegenden Fakten solltest Du die DB in jedem Fall 
ändern: <https://de.wikipedia.org/wiki/Normalisierung_(Datenbank)>

> > RTFM: <http://php.net/manual/en/pdostatement.bindcolumn.php>
> 
> Ich kauf mirn Buch. Kein Scherz.

Naturgemäss wird kein Buch über PHP, insbesondere kein deutschsprachiges, 
jemals so aktuell und wenig fehlerbehaftet sein wie das von den an PHP und 
PHP-Projekten Beteiligten im Web veröffentlichte PHP-Handbuch, insbesondere 
wie seine originale englischsprachige Version.

-- 
PointedEars
Zend Certified PHP Engineer
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#3551

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-11-15 14:23 +0100
Message-ID<15739846.o4CBAyVrKO@PointedEars.de>
In reply to#3547
Peter Müller wrote:

> CREATE TABLE wiealt2 (
> `id` int(11) NOT NULL,
> `jahr` smallint(5) unsigned DEFAULT NULL,
> `baldwin` int(10) unsigned DEFAULT NULL)
> ENGINE=MyISAM DEFAULT CHARSET=utf8;
> 
> INSERT INTO `wiealt2` (`id`, `jahr`, `baldwin`) VALUES
> (1, 1700, NULL),
> (10, 1810, 11),
> (11, 1811, 12),
> (12, 1812, 13),
> (13, 1813, 14),
> (14, 1814, 15),
> (15, 1815, 16),
> (16, 1816, 17),
> (17, 1817, 18),
> (18, 1818, 19),
> (19, 1819, NULL),
> (99, 1899, NULL);
> 
> $firma = 'baldwin';
> $nummer = '15';
> 
> $query1 = "SELECT max(jahr) as maxjahr FROM wiealt2 WHERE :firma <=
> :nummer";
> $stmt = $dbmerz -> prepare($query1);
> $stmt -> bindValue(':firma', $firma, PDO::PARAM_STR);
> $stmt -> bindValue(':nummer', $nummer, PDO::PARAM_INT);
> $stmt -> execute();
> $result1 = $stmt->fetchAll(PDO::FETCH_OBJ);
> if($result1)
> {
> $min=$result1[0]->maxjahr;
> var_dump($result1);
> }
> $query2 = "SELECT min(jahr) as minjahr FROM wiealt2 WHERE :firma >
> :nummer"; $stmt = $dbmerz -> prepare($query2);
> $stmt -> bindValue(':firma', $firma, PDO::PARAM_STR);
> $stmt -> bindValue(':nummer', $nummer, PDO::PARAM_INT);
> $stmt -> execute();
> $result2 = $stmt->fetchAll(PDO::FETCH_OBJ);
> if($result2)
> {
> $max=$result2[0]->minjahr;
> var_dump($result2);
> }
> print "<p>Nummer = $nummer; Firma = $firma; Min = $min, Max = $max.</p>";
> 
> Ausgabe: array(1) { [0]=> object(stdClass)#86 (1) { ["maxjahr"]=> NULL }
> } array(1) { [0]=> object(stdClass)#87 (1) { ["minjahr"]=> string(4)
> "1700" } }
> 
> Nummer = 15; Firma = baldwin; Min = , Max = 1700.
> 
> SQL-Ausgabe ist aber dagegen:
> mysql> SELECT max(jahr) as maxjahr FROM wiealt2 WHERE baldwin <= 15;
> +---------+
> | maxjahr |
> +---------+
> |    1814 |
> +---------+
> 1 row in set (0.01 sec)
> mysql> SELECT min(jahr) as minjahr FROM wiealt2 WHERE baldwin > 15;
> +---------+
> | minjahr |
> +---------+
> |    1815 |
> +---------+
> 1 row in set (0.00 sec)
> 
> Der PHP-Code liefert also NULL, 1700, SQL liefert 1814,1815 auf dieselbe
> Abfrage. Mir scheint, die WHERE-Abfrage wird hier verworfen. Wieso?

Es sind _nicht_ dieselben Abfragen und die WHERE-_Bedingung_ der _SELECT_-
Abfrage wird höchstens teilweise verworfen.  Denn:

In Prepared Statements (PSs) mindestens mit mysqli und PDO_MySQL können 
Namen keine ersetzten Werte sein (kann BTW in einer Frage in der ZCE-Prüfung 
vorkommen, siehe Trainingsmaterial).

Denn Deine PSs

  SELECT max(jahr) as maxjahr FROM wiealt2 WHERE :firma <= :nummer

bzw.

  SELECT min(jahr) as minjahr FROM wiealt2 WHERE :firma > :nummer

sind mit den verwendeten Wertbindungen äquivalent zu

  SELECT MAX(`jahr`) AS `maxjahr` FROM `wiealt2` WHERE 'baldwin' <= 15;

bzw.

  SELECT MIN(`jahr`) AS `minjahr` FROM `wiealt2` WHERE 'baldwin' > 15;

Es wird also nicht mit dem Wert der Feldes in der Spalte `baldwin` des 
jeweiligen Datensatzes, sondern mit dem fixen String-Wert 'baldwin' 
verglichen.  Da das nicht sinnvoll ist (der zweite Operand ist eine Zahl), 
wird der String gekürzt.  Debugging-Beispiel mit Deiner Tabelle (bei mir 
`tmp`:

,----
| $ mysql -u root -p                                                                                                                                   
| Enter password:                                                                                                                                      
| Welcome to the MySQL monitor.  Commands end with ; or \g.
| Your MySQL connection id is 106
| Server version: 5.6.25-3 (Debian)
| 
| Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights 
| reserved.
| 
| Oracle is a registered trademark of Oracle Corporation and/or its
| affiliates. Other names may be trademarks of their respective
| owners.
| 
| Type 'help;' or '\h' for help. Type '\c' to clear the current input 
| statement.
| 
| mysql> use tmp;
| Reading table information for completion of table and column names
| You can turn off this feature to get a quicker startup with -A
| 
| Database changed
| mysql> SELECT * FROM `tmp`;
| +----+------+---------+
| | id | jahr | baldwin |
| +----+------+---------+
| |  1 | 1700 |    NULL |
| | 10 | 1810 |      11 |
| | 11 | 1811 |      12 |
| | 12 | 1812 |      13 |
| | 13 | 1813 |      14 |
| | 14 | 1814 |      15 |
| | 15 | 1815 |      16 |
| | 16 | 1816 |      17 |
| | 17 | 1817 |      18 |
| | 18 | 1818 |      19 |
| | 19 | 1819 |    NULL |
| | 99 | 1899 |    NULL |
| +----+------+---------+
| 12 rows in set (0.00 sec)
| 
| mysql> SELECT * FROM `tmp` WHERE 'baldwin' <= 15;
| +----+------+---------+
| | id | jahr | baldwin |
| +----+------+---------+
| |  1 | 1700 |    NULL |
| | 10 | 1810 |      11 |
| | 11 | 1811 |      12 |
| | 12 | 1812 |      13 |
| | 13 | 1813 |      14 |
| | 14 | 1814 |      15 |
| | 15 | 1815 |      16 |
| | 16 | 1816 |      17 |
| | 17 | 1817 |      18 |
| | 18 | 1818 |      19 |
| | 19 | 1819 |    NULL |
| | 99 | 1899 |    NULL |
| +----+------+---------+
| 12 rows in set, 1 warning (0.00 sec)
| 
| mysql> SHOW WARNINGS;
| +---------+------+---------------------------------------------+
| | Level   | Code | Message                                     |
| +---------+------+---------------------------------------------+
| | Warning | 1292 | Truncated incorrect DOUBLE value: 'baldwin' |
| +---------+------+---------------------------------------------+
| 1 row in set (0.00 sec)
| 
| mysql> SELECT MAX(`jahr`) FROM `tmp` WHERE 'baldwin' <= 15;
| +-------------+
| | MAX(`jahr`) |
| +-------------+
| |        1899 |
| +-------------+
| 1 row in set, 1 warning (0.00 sec)
| 
| mysql> SELECT MIN(`jahr`) FROM `tmp` WHERE 'baldwin' > 15;
| +-------------+
| | MIN(`jahr`) |
| +-------------+
| |        NULL |
| +-------------+
| 1 row in set, 1 warning (0.00 sec)
`----

[Dieselben Ergebnisse erhalte ich auch über PHP.  Weshalb bei Dir angeblich 
für das Ergebnis der ersten Abfrage NULL und für das der zweiten 1700 
geliefert wird statt 1899 und NULL, ist mir noch nicht klar.  Klar ist aber, 
dass die Abfragen so nicht funktionieren *können*.]

Du musst stattdessen den Spaltennamen mit String-Konkatenation oder 
sprintf() in die Abfrage einbauen und solltest ihn dann geeignet (MySQL: 
mindestens mit `…`) escapen, so wie Du es anfangs getan hast.  (Da man das 
immer wieder braucht, schreibt man sich dafür entweder eine Datenbank-
Klasse, so wie ich es für mein PHPX-Framework [1] für die ECMAScript Support 
Matrix [2] getan habe, oder verwendet zum Beispiel die Datenbank-Klassen des 
Zend Framework 2 [3].)

Für eine einmalige Abfrage kannst Du übrigens PDOStatement::execute() ein 
assoziatives Array aus Werten übergeben.  Wertbindung ist nur 
sinnvoll/nötig, wenn die ansonsten gleiche Abfrage mehrfach mit 
unterschiedlichen Werten ausgeführt wird.  Und dann ist es nur sinnvoll, das 
jeweilige PDOStatement *einmal* zu erstellen und nur die Wertbindung zu 
ändern oder Parameter zu binden (PDOStatement::bindParam()) und nur die 
Werte der gebundenen Variablen zu ändern.

Bezüglich Codestil rate ich Dir:

- Keine Zeilen über die 80. Spalte hinaus (für Usenet: nicht über die 76. 
  Spalte hinaus)

- Nur Operatoren werden immer von Whitespace umschlossen.  “->” ist i.e.S.
  in PHP *kein* Operator¹:

  <http://php.net/manual/en/language.operators.php>

- “if” ist kein Funktionsbezeichner, sondern das Schlüsselwort einer 
  Steueranweisung; nach solchen steht immer ein Leerzeichen:

    if ($result1) …

- Bei Anweisungsblöcken wird nicht die erste geschweifte Klammer eingerückt,
  sondern nur der Inhalt des Blocks.

- Ganz allgemein: Whitespace wird konsistent verwendet.  Also zum Beispiel 
  nicht

    $dbmerz -> prepare($query2)

  und dann wieder

    $stmt->fetchAll(PDO::FETCH_OBJ)

  oder mal

    $stmt = $dbmerz -> prepare($query2);

  und dann wieder

    $max=$result2[0]->minjahr;

  Mit einer PHP-Entwicklungsumgebung wie zum Beispiel Eclipse PDT oder
  Zend Studio wird das einfacher.

- Alle Schlüsselwörter und Bezeichner eingebauter Funktionen in
  SQL-Anweisungen werden durchgängig gross geschrieben; andere Namen
  werden durchgängig so geschrieben, wie sie erstellt wurden
  (Empfehlung: Kleinschreibung mit Unterstrich) und gequotet (“MIN(`jahr`).

- Namen von Tabellen sollten Entitäten beschreiben und optimal auf Englisch
  sein, also nicht “wiealt2”, sondern “company_age”.  Bezüglich Englisch
  gilt dasselbe für Namen von Datenbanken, Spalten und Stored Procedures.

Ein leicht lesbarer Quelltext trägt viel dazu bei, Fehler im Quelltext zu 
finden und auszumerzen.  Das gilt sowohl für den Fall, dass Du Fehler in 
Deinem Quelltext finden musst als auch, dass andere Deinen Quelltext 
verstehen sollen.

Allerdings macht Deine Datenbank allgemein einen falsch strukturierten 
Eindruck: “baldwin” ist anscheinend der Name einer Firma (Du vergleichst mit 
einem Wert mit dem Platzhalter “:firma”); eine Spalte namens “baldwin” 
sollte es deshalb gar nicht geben, sondern 'baldwin' bzw. die ID von 
“baldwin” sollte ein *Wert* in einem *Feld* einer Spalte sein.  Das könnte 
man weiter in <news:de.comp.datenbanken.mysql> diskutieren.

[1] <http://PointedEars.de/wsvn/PHPX/trunk/Db/>
[2] <http://PointedEars.de/es-matrix/>
[3] 
<http://framework.zend.com/apidoc/2.4/classes/Zend.Db.Adapter.Platform.Mysql.html>

_________
¹ Ja, ich kenne T_OBJECT_OPERATOR und 
  <http://php.net/manual/en/language.oop5.properties.php>
-- 
PointedEars
Zend Certified PHP Engineer
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#3554

FromPeter Müller <peter.mueller@c-major.de>
Date2015-11-15 14:39 +0100
Message-ID<n2a1v0$3a3$2@news.albasani.net>
In reply to#3551
Thomas 'PointedEars' Lahn schrieb am 15.11.2015 um 14:23:
> 
> Bezüglich Codestil rate ich Dir:
> 
> - Keine Zeilen über die 80. Spalte hinaus (für Usenet: nicht über die 76. 
>   Spalte hinaus)
> 
> - Nur Operatoren werden immer von Whitespace umschlossen.  “->” ist i.e.S.
>   in PHP *kein* Operator¹:
> 
>   <http://php.net/manual/en/language.operators.php>
> 
> - “if” ist kein Funktionsbezeichner, sondern das Schlüsselwort einer 
>   Steueranweisung; nach solchen steht immer ein Leerzeichen:
> 
>     if ($result1) …
> 
> - Bei Anweisungsblöcken wird nicht die erste geschweifte Klammer eingerückt,
>   sondern nur der Inhalt des Blocks.
> 
> - Ganz allgemein: Whitespace wird konsistent verwendet.  Also zum Beispiel 
>   nicht
> 
>     $dbmerz -> prepare($query2)
> 
>   und dann wieder
> 
>     $stmt->fetchAll(PDO::FETCH_OBJ)
> 
>   oder mal
> 
>     $stmt = $dbmerz -> prepare($query2);
> 
>   und dann wieder
> 
>     $max=$result2[0]->minjahr;
> 
>   Mit einer PHP-Entwicklungsumgebung wie zum Beispiel Eclipse PDT oder
>   Zend Studio wird das einfacher.
> 
> - Alle Schlüsselwörter und Bezeichner eingebauter Funktionen in
>   SQL-Anweisungen werden durchgängig gross geschrieben; andere Namen
>   werden durchgängig so geschrieben, wie sie erstellt wurden
>   (Empfehlung: Kleinschreibung mit Unterstrich) und gequotet (“MIN(`jahr`).
> 
> - Namen von Tabellen sollten Entitäten beschreiben und optimal auf Englisch
>   sein, also nicht “wiealt2”, sondern “company_age”.  Bezüglich Englisch
>   gilt dasselbe für Namen von Datenbanken, Spalten und Stored Procedures.

Das werde ich in Zukunft ändern!

Viele Grüße,

Peter

[toc] | [prev] | [next] | [standalone]


#3560

FromArno Welzel <usenet@arnowelzel.de>
Date2015-11-16 08:43 +0100
Message-ID<5649891E.4060409@arnowelzel.de>
In reply to#3545
Peter Müller schrieb am 2015-11-14 um 22:19:

> Arno Welzel schrieb am 14.11.2015 um 21:32:
>> Peter Müller schrieb am 2015-11-14 um 20:54:
>>
>>> Hallo,
>>>
>>> ich arbeite mich gerade mit PDO ein und komme an einem Punkt nicht
>>> weiter, ich hoffe ihr könnt mir helfen. Es geht um die Umsetzung dieser
>>> SQL-Abfrage:
>>> mysql> SELECT min(jahr) as minjahr
>>>     -> FROM wiealt
>>>     -> WHERE baldwin > 100000;
>>> +---------+
>>> | minjahr |
>>> +---------+
>>> |    1950 |
>>> +---------+
>>> 1 row in set (0.00 sec)
>>>
>>> Mein (reduziertes) PDO-Codeschnipsel sieht so aus:
>>>
>>> $firma = 'baldwin';
>>> $nummer = 100000;
>>> $query2 = "
>>> 	SELECT min(jahr) as minjahr
>>> 	FROM wiealt
>>> 	WHERE :firma > :nummer";
>>
>> Wieso nicht in einer Zeile? Eine Aufteilung auf mehrere Zeilen sollte
>> auch eher so aussehen:
>>
>> $query2 = "SELECT min(jahr) as minjahr ".
>>           "FROM wiealt ".
>>           "WHERE :firma > :nummer";
> 
> Ist nur übersichtlicher. Es erscheint auch keine notice deswegen, aber
> ich kann's natürlich gerne mal mit einer einzeiligen query testen.

Ah - Wald und Bäume.

Prepared statements sind dafür gedacht, die *Werte* als Parameter zu
binden, nicht Spaltennamen.

Statt

SELECT min(jahr) as minjahr FROM wiealt WHERE :firma > :nummer

muss es lauten:

SELECT min(jahr) as minjahr FROM wiealt WHERE baldwin > :nummer

Und dann eben nur :nummer als Parameter setzen.


-- 
Arno Welzel
http://arnowelzel.de
http://de-rec-fahrrad.de
http://fahrradzukunft.de

[toc] | [prev] | [next] | [standalone]


#3563

FromPeter Müller <peter.mueller@c-major.de>
Date2015-11-16 21:23 +0100
Message-ID<n2ddv4$j1r$1@news.albasani.net>
In reply to#3560
Arno Welzel schrieb am 16.11.2015 um 08:43:
> Peter Müller schrieb am 2015-11-14 um 22:19:
> 
>> Arno Welzel schrieb am 14.11.2015 um 21:32:
>>> Peter Müller schrieb am 2015-11-14 um 20:54:
>>>
>>>> Hallo,
>>>>
>>>> ich arbeite mich gerade mit PDO ein und komme an einem Punkt nicht
>>>> weiter, ich hoffe ihr könnt mir helfen. Es geht um die Umsetzung dieser
>>>> SQL-Abfrage:
>>>> mysql> SELECT min(jahr) as minjahr
>>>>     -> FROM wiealt
>>>>     -> WHERE baldwin > 100000;
>>>> +---------+
>>>> | minjahr |
>>>> +---------+
>>>> |    1950 |
>>>> +---------+
>>>> 1 row in set (0.00 sec)
>>>>
>>>> Mein (reduziertes) PDO-Codeschnipsel sieht so aus:
>>>>
>>>> $firma = 'baldwin';
>>>> $nummer = 100000;
>>>> $query2 = "
>>>> 	SELECT min(jahr) as minjahr
>>>> 	FROM wiealt
>>>> 	WHERE :firma > :nummer";
>>>
>>> Wieso nicht in einer Zeile? Eine Aufteilung auf mehrere Zeilen sollte
>>> auch eher so aussehen:
>>>
>>> $query2 = "SELECT min(jahr) as minjahr ".
>>>           "FROM wiealt ".
>>>           "WHERE :firma > :nummer";
>>
>> Ist nur übersichtlicher. Es erscheint auch keine notice deswegen, aber
>> ich kann's natürlich gerne mal mit einer einzeiligen query testen.
> 
> Ah - Wald und Bäume.
> 
> Prepared statements sind dafür gedacht, die *Werte* als Parameter zu
> binden, nicht Spaltennamen.
> 
> Statt
> 
> SELECT min(jahr) as minjahr FROM wiealt WHERE :firma > :nummer
> 
> muss es lauten:
> 
> SELECT min(jahr) as minjahr FROM wiealt WHERE baldwin > :nummer
> 
> Und dann eben nur :nummer als Parameter setzen.

Ja. Ich schreibe mal demnächst in de.comp.datenbanken.mysql weiter, wie
den meine Tabelle mit den Seriennummern aussehen müsste ...

Danke erstmal,

Peter

[toc] | [prev] | [next] | [standalone]


#3550

FromThomas Mlynarczyk <thomas@mlynarczyk-webdesign.de>
Date2015-11-15 13:09 +0100
Message-ID<n29slc$p69$1@news.albasani.net>
In reply to#3544
On 14/11/15 21:32, Arno Welzel wrote:
> Peter Müller schrieb am 2015-11-14 um 20:54:
>> $query2 = "
>> 	SELECT min(jahr) as minjahr
>> 	FROM wiealt
>> 	WHERE :firma > :nummer";
>
> Wieso nicht in einer Zeile? Eine Aufteilung auf mehrere Zeilen sollte
> auch eher so aussehen:
>
> $query2 = "SELECT min(jahr) as minjahr ".
>            "FROM wiealt ".
>            "WHERE :firma > :nummer";

Warum? Peters Schreibweise ist doch völlig in Ordnung (was die 
"Mehrzeiligkeit" betrifft). Selbstverständlich darf ein String auch 
CR/LF usw. enthalten. Und MySQL schert sich nicht um zusätzlichen 
Whitespace.

Gruß,
Thomas

-- 
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)

[toc] | [prev] | [next] | [standalone]


#3567

FromMarkus Grob <snoopy@ilnet.ch>
Date2015-11-17 09:48 +0100
Message-ID<n2epfv$3o6$2@dont-email.me>
In reply to#3550
Thomas Mlynarczyk schrieb:
> On 14/11/15 21:32, Arno Welzel wrote:
>> Peter Müller schrieb am 2015-11-14 um 20:54:
>>> $query2 = "
>>>     SELECT min(jahr) as minjahr
>>>     FROM wiealt
>>>     WHERE :firma > :nummer";
>>
>> Wieso nicht in einer Zeile? Eine Aufteilung auf mehrere Zeilen sollte
>> auch eher so aussehen:
>>
>> $query2 = "SELECT min(jahr) as minjahr ".
>>            "FROM wiealt ".
>>            "WHERE :firma > :nummer";
>
> Warum? Peters Schreibweise ist doch völlig in Ordnung (was die
> "Mehrzeiligkeit" betrifft). Selbstverständlich darf ein String auch
> CR/LF usw. enthalten. Und MySQL schert sich nicht um zusätzlichen
> Whitespace.

Natürlich. Es geht hier nur um die Darstellung. Die vorgeschlagene 
Version zeigt gleich, welche Variable den SELECT enthält und die 
originale Version erlaubt weniger tiefe Einrückung. Ich bevorzuge die 
gleiche Zeile doch codetechnisch ist es wirklich irrelevant.

Gruss, Markus

[toc] | [prev] | [next] | [standalone]


#3569

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-11-17 20:13 +0100
Message-ID<25405015.omH6QaEoAq@PointedEars.de>
In reply to#3567
Markus Grob wrote:

> Thomas Mlynarczyk schrieb:
>> On 14/11/15 21:32, Arno Welzel wrote:
>>> Peter Müller schrieb am 2015-11-14 um 20:54:
>>>> $query2 = "
>>>>     SELECT min(jahr) as minjahr
>>>>     FROM wiealt
>>>>     WHERE :firma > :nummer";
>>>
>>> Wieso nicht in einer Zeile? Eine Aufteilung auf mehrere Zeilen sollte
>>> auch eher so aussehen:
>>>
>>> $query2 = "SELECT min(jahr) as minjahr ".
>>>            "FROM wiealt ".
>>>            "WHERE :firma > :nummer";
>>
>> Warum? Peters Schreibweise ist doch völlig in Ordnung (was die
>> "Mehrzeiligkeit" betrifft). Selbstverständlich darf ein String auch
>> CR/LF usw. enthalten. Und MySQL schert sich nicht um zusätzlichen
>> Whitespace.
> 
> Natürlich. Es geht hier nur um die Darstellung. Die vorgeschlagene
> Version zeigt gleich, welche Variable den SELECT enthält

Das tut das Original auch.

> und die originale Version erlaubt weniger tiefe Einrückung.

Das kann man mit Deinem Ansatz auch erreichen.  Allerdings ist das 
wichtigste Gegenargument gegen Deinen Ansatz die Effizienz: es müssen 
zusätzlich Konkatenationsoperationen durchgeführt werden.

> Ich bevorzuge die gleiche Zeile doch codetechnisch ist es wirklich 
> irrelevant.

Ich bevorzuge es, keine SQL-Statements in meinen PHP-Programmen zu haben 
(diese passend für die verwendete Datenbank-Sprache zusammenzubauen erledigt 
grösstenteils meine Datenbank-Klasse, deren Methoden von Controller-Methoden 
aufgerufen werden, die ich aufrufe), aber falls SQL-Snippets im PHP-Code 
nötig sein sollten, bevorzuge ich String-Literale mit Zeilenumbrüchen.

Beispiel: <http://PointedEars.de/wsvn/es-matrix/trunk/application/models/mappers/ResultMapper.php>

(Wie man sieht, sind die Abfragen hier noch teilweise abhängig von der 
Datenbanksprache.  Im Zend Framework etwa wird auch dies mittels Chaining 
abstrahiert; der Preis dafür ist ein Objekt je dann weniger offensichtliche 
Abfrage.  Ich brauchte bisher zuwenig komplexe JOINs, um dies in PHPX 
einzubauen.)

-- 
PointedEars
Zend Certified PHP Engineer
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | de.comp.lang.php


csiph-web