db_query nie FALSE, NULL o. ä. ?
Eingetragen von raffi (21)
am 12.06.2012 - 12:42 Uhr in
am 12.06.2012 - 12:42 Uhr in
Hallo Community,
ich bin gerade am Schreiben eines kleinen Moduls und stolpere dabei über das Resultat von db_query. Ich habe eine Abfrage, welche ein Ergebnis liefert oder eben nicht. Im letzteren Falle soll eben die Ausgabe anders sein, als selbige mit Ergebnis der Abfrage.
Soweit die Theorie. Versucht habe ich das ganze praktisch bereits folgendermaßen:
- if (!$result)
- if ($result == FALSE)
- if ($result)...else...
- $rows = db_affected_rows();
if ($rows == 0)... - if ($data = db_fetch_object($result))...else...
Ich hoffe, ich habe jetzt keine Möglichkeit vergessen, welche ich schon durchexerziert habe. Fragen ergeben sich bei mir dadurch zwei.
- Wie lautet der Rückgabewert von db_query, falls die Abfrage kein Ergebnis liefert?
- Was gibt es noch für einen Weg um das gewünschte Verhalten zu bekommen?
Zu guter letzt noch der Codeschnipsel zum Problem:
<?php
# page callback
function show_projects () {
# Array mit dem Zeileninhalten
$rows = array();
# Array mit den Spaltenüberschriften
$header = array(
array('data' => "ID"),
array('data'=> "Vorgangsname"),
array('data' => "Manntage"),
array('data' => "verbl. Zeitkontingent"),
);
$sql = "
select
na.title,
na.nid,
nra.body,
caf.field_auftrag_manntage_value,
na.type,
na.vid
from
node na
left join
content_type_auftrag caf
on
na.vid = caf.vid
inner join
node nk
on
caf.field_auftragskategorie_nid = nk.nid
left join
node_revisions nra
on
na.vid = nra.vid
left join
node_revisions nrk
on
nk.vid = nrk.vid
where
(caf.field_pr_anzeigen_value = '%d')
and
(caf.field_auftrag_manntage_value IS NOT NULL)
group by
na.title
";
$result = db_query($sql, 1);
# Typen festlegen für spätere
# Abfrage ob AZ zu Aufrag
# bereits vorhanden
$type_project = "auftrag";
$type_working_time = "arbeitszeit";
while ($data = db_fetch_object($result)) {
$node = node_load($data->nid);
# gibt es bereits AZ zu aktuellem Auftrag?
# wenn ja berechne Restzeit
$sql_az = "
select
round
(
((caf.field_auftrag_manntage_value*8*3600) -
sum(UNIX_TIMESTAMP(caz.field_ende_value)-
UNIX_TIMESTAMP(caz.field_beginn_value))) / 3600, 2
) as rest
from
content_type_arbeitszeit caz
join
node naf
on
naf.nid = caz.field_auftrag_nid
join
node_revisions nraf
on
nraf.vid = naf.vid
join
node naz
on
naz.vid = caz.vid
join
content_type_auftrag caf
on
caf.vid = naf.vid
where
naf.title = '%s'
and
naf.type = '%s'
and
naz.type = '%s'
";
$result_az = db_query($sql_az, $node->title, $type_project, $type_working_time);
# bereits AZ erfasst
if ($result_az) {
$remaining_time = db_fetch_object($result_az);
$rows[] = array(
"id" => $node->title,
"body" => $node->body,
"kurztext" => $node->field_auftrag_manntage[0]['value'],
"rest" => $remaining_time->rest,
);
}
# bisher keine AZ erfasst
else {
$rows[] = array(
"id" => $node->title,
"kurztext" => $node->body,
"manntage" => $node->field_auftrag_manntage[0]['value'],
"rest" => $node->field_auftrag_manntage[0]['value'] * 8,
);
}
}
return theme('table', $header, $rows);
}
?>
Danke und viele Grüße
- Anmelden oder Registrieren um Kommentare zu schreiben
An welcher Stelle im
am 12.06.2012 - 15:37 Uhr
An welcher Stelle im Codeschnippsel besteht denn dein Problem?
Hallo,der Fehler, wenn man
am 13.06.2012 - 06:51 Uhr
Hallo,
der Fehler, wenn man ihn so nennen will tritt dort auf:
<?php
...
$result_az = db_query($sql_az, $node->title, $type_project, $type_working_time);
# bereits AZ erfasst
if ($result_az) {
$remaining_time = db_fetch_object($result_az);
$rows[] = array(
"id" => l($node->title, 'node/'.$node->nid),
"body" => $node->body,
"kurztext" => $node->field_auftrag_manntage[0]['value'],
"rest" => $remaining_time->rest,
);
}
# bisher keine AZ erfasst
# id, kurztext und manntage werden jedoch mit Inhalt gefüllt
# dieser Codeschnipsel allein zeigt jedoch das richtige
# vollständige Ergebnis an
else {
$rows[] = array(
"id" => $node->title,
"kurztext" => $node->body,
"manntage" => $node->field_auftrag_manntage[0]['value'],
"rest" => $node->field_auftrag_manntage[0]['value'] * 8,
);
}
...
?>
In der Anzeige der Tabelle bleiben die Zellen der entsprechenden Ergebnisse einfach leer.
Was mir beim Schreiben gerade auffällt: Alle anderen Daten, bis auf die Spalte "rest" werden jedoch mit entsprechendem Inhalt angezeigt. Wenn ich explizit nur den Codeschnipsel im else-Zweig ausführen lasse, werden die berechneten Ergebnisse richtig angezeigt.
Viele Grüße
Hast du die SQL-Abfrage schon
am 13.06.2012 - 16:48 Uhr
Hast du die SQL-Abfrage schon mal im phpMyAdmin oder so ausprobiert, um zu prüfen, ob die Abfrage an sich überhaupt stimmt?
Hallo,beide Abfragen
am 14.06.2012 - 14:35 Uhr
Hallo,
beide Abfragen funktionieren tadellos. Ich erhalte ja komischerweise auch alle Daten, bis auf diese "popelige" Berechnung ($node->field_auftrag_personentage[0]['value'] * 8) wird ja auch jedes Feld mit dem entsprechendem Inhalt angezeigt. Da allerdings die Berechnung funktioniert, wenn ich diese für ausnahmslos jede Zeile so machen lasse, hatte ich schonmal an ein eher PHP lastiges Problem gedacht:
Mit "rest" => $remaining_time->rest, schreibe ich evtl einen String in die Zelle.
Mit $node->field_auftrag_personentage[0]['value'] * 8 wiederum habe ich einen Integer-Wert.
Ergebnis wäre zwar ein assoziatives Array, aber an der Stelle rest hätte es unterschiedliche Datentypen stehen. Könnte der Gedankengang korrekt sein?
Viele Grüße
EDIT: Wenn ich aus "rest" => $remaining_time->rest, --> "rest" => floatval($remaining_time->rest), mache zeigt er schonmal in jeder Zeile etwas an. Allerdings an den Stellen wo er trivialerweise mit 8 multiplizieren soll steht eine Null.
Was schonmal festzuhalten bleibt: Es scheint kein Drupalproblem zu sein. ;D
Mach mal das hier, um zu
am 14.06.2012 - 14:39 Uhr
Mach mal das hier, um zu prüfen, ob in deinem SQL-Ergebnis überhaupt etwas steht:
<?php drupal_set_message('<pre>' . print_r($remaining_time, 1) . '</pre>'); ?>
Das dürfte dir das Ergebnis deiner Abfrage ausgeben, wenn da nichts kommt, dürfte es an der Abfrage liegen.
Hallo,nachdem ich
am 15.06.2012 - 10:00 Uhr
Hallo,
nachdem ich feststellen musste, dass sich meine Annahme mit dem Typenproblem im Sand verlaufen hat, hab ich ein bisschen weiter probiert.
Löse das ganze nun genau so unkompliziert wie vorher, nur dass ich die if-Abfrage etwas tiefer vornehme:
<?php
while ($data = db_fetch_object($result)) {
$node = node_load($data->nid);
$sql_az = sql_az();
$result_az = db_query($sql_az, $node->title, $type_project, $type_working_time);
$remaining_time = db_fetch_object($result_az);
if ($remaining_time->rest != NULL) {
$rows[] = array(
"id" => $node->title,
"kurtext" => l($node->body, 'node/'.$node->nid),
"personentage" => $node->field_auftrag_personentage[0]['value'],
"rest" => $remaining_time->rest." h",
);
}
else {
$rows[] = array(
"id" => $node->title,
"kurtext" => l($node->body, 'node/'.$node->nid),
"personentage" => $node->field_auftrag_personentage[0]['value'],
"rest" => ($node->field_auftrag_personentage[0]['value']*8)." h",
);
}
}
?>
Ich frage also jetzt direkt die Stelle im geholten Objekt ab, anstatt zu Fragen ob db_query erfolgreich war.
Meine Abfrage
<?php
select
round
(
((caf.field_auftrag_personentage_value*8*3600) -
sum(UNIX_TIMESTAMP(caz.field_ende_value)-
UNIX_TIMESTAMP(caz.field_beginn_value))) / 3600, 2
) as rest
from
content_type_arbeitszeit caz
join
node naf
on
naf.nid = caz.field_auftrag_nid
join
node_revisions nraf
on
nraf.vid = naf.vid
join
node naz
on
naz.vid = caz.vid
join
content_type_auftrag caf
on
caf.vid = naf.vid
where
naf.title = '%s'
and
naf.type = '%s'
and
naz.type = '%s'
?>
liefert durch das explizite Setzen des Ergebnisfeldes als Spalte rest diese mit dem Inhalt NULL zurück. Also war das Objekt immer da, nur hatte es eben an dieser wichtigen Stelle entweder einen Zahlenwert (als string!?) bzw. NULL stehen.
So sieht zumindest meine Theorie aus.
Viele Grüße und danke für die Hilfe.
Nur als Info, PHP
am 15.06.2012 - 10:15 Uhr
Nur als Info, PHP unterscheidet nicht wirklich zwischen den Typen "String" und "Integer". Man kann diese Unterscheidung treffen, aber allgemein passiert das nicht.
Das hier:
<?php "123" == 123 ?>
liefert also TRUE, weil PHP einen String, der nur eine Zahl enthält, bei Bedarf zu einer Zahl parst. Allerdings gibt's noch den typsicheren Vergleich (===), der prüft, ob der Inhalt gleich ist UND ob der Typ übereinstimmt.Demnach liefert
<?php "123" === 123 ?>
also FALSE, weil das eine ein String und das andere eine Zahl ist.Genauso verhält es sich mit der TRUE/FALSE-Prüfung bei der Zahl 0. 0 wird als FALSE interpretiert.
<?php 0 == FALSE ?>
geht also klar.<?php 0 === FALSE ?>
hingegen nicht, weil 0 eine Zahl und FALSE ein Boolean-Wert ist.