it-swarm.com.de

Wie schreibe ich eine Abfrage mit einer WHERE-Klausel mit zwei Bedingungen?

Es scheint nicht möglich zu sein, dass diese select-Anweisung mit den WHERE-Bedingungen funktioniert. Je nachdem, wie die Daten geladen werden, erhalte ich entweder das erste Testergebnis oder alle Testergebnisse und nicht das von mir gewünschte benutzerspezifische Ergebnis.

Ich habe die Dokumentation immer wieder durchgesehen und weiß, dass dies einfach ist, aber ich kann nicht herausfinden, was los ist. Ich habe die Funktion getUser() separat geprüft und es funktioniert einwandfrei, die Funktion test_id Bedingung scheint nicht zu funktionieren.

$db = JFactory::getDbo();
$user = JFactory::getUser();
$query = $db->getQuery(true);

$query -> SELECT('Test_Percentile');
$query -> FROM($db->quoteName('#__calc_results'));
$query -> WHERE(($db->quoteName('test_id').'='.'1')AND($db- 
>quoteName('user_id').'='.($user->id)));

$db->setQuery($query);
$result = $db->loadObject();

echo "<p>" . $result->Test_Percentile ."</p>";
1
BabyCode123

Versuche dies:

$query->WHERE($db->quoteName('test_id').'= 1 AND '.$db->quoteName('user_id').'='. $user->id)
2
Terry Carter

Was ist schief gelaufen?

Sie haben versehentlich einen gültigen Ausdruck gebildet, der zwei durch AND getrennte Bedingungen enthält.

($db->quoteName('test_id').'='.'1')AND($db->quoteName('user_id').'='.($user->id))

ist dasselbe wie alle folgenden: ( Demo )

("`test_id`=1")AND("`user_id`=$user->id")
"`test_id`=1" && "`user_id`=$user->id"
true && true
true

Wenn Sie den Booleschen Wert true in einen String konvertieren, wird er zu 1.

Wie können Sie Ihr Problem untersuchen?

Sie können den generierten 1 Sehen, wenn Sie zu System> Globale Konfiguration gehen, dann unter System = Tab, setzen Sie im Abschnitt Debug Settings das Feld Debug System auf Yes. Laden Sie dann Ihr Skript neu, klicken Sie unten auf Ihrer Seite auf das Kontrollkästchen Datenbankabfragen, um alle ausgeführten Abfragen anzuzeigen, und scrollen Sie dann nach unten, bis Sie Ihre Abfrage gefunden haben. Folgendes würden Sie sehen:

SELECT Test_Percentile FROM [prefix]_calc_results WHERE 1

Abgesehen davon, dass die generierte Abfrage nicht Ihren Wünschen entspricht, werden Sie auch feststellen, dass die Anzahl der zurückgegebenen Zeilen alle Zeilen in Ihrer Datenbanktabelle sind, da WHERE 1 Effektiv nichts herausfiltert. Sie verwenden $db->loadObject() in Ihrem PHP-Code, so dass trotz aller Zeilen, die in der Ergebnismenge geliefert werden, nur auf die erste Zeile zugegriffen und diese angezeigt wird.

Einige Best Practices-Vorschläge:

Abgesehen von der Festlegung Ihrer Abfragesyntax möchte ich Ihnen eine Reihe weiterer Verbesserungen für Ihre zukünftigen Entwicklungsprojekte empfehlen, mit denen Sie Ihren Code sauber, lesbar, effizient und leicht zu debuggen halten können.

  1. Verwenden Sie "Verkettung" aus Ihrer ersten Deklaration von $query. Dies bedeutet, dass Sie -> Verwenden, um Ihre Methodenaufrufe zu verbinden, die alle für $query Gelten, anstatt in jeder Zeile $query Zu schreiben.
  2. Verwenden Sie Methodenaufrufe in Kleinbuchstaben, um die Anzeige der Joomla-Dokumentation widerzuspiegeln.
  3. Da für keine Ihrer Tabellen oder Spaltennamen ein Backtick-Wrapping erforderlich ist, um die Abfrage gültig zu machen, können Sie das Aufblähen des Codes vermeiden und diese Aufrufe auslassen. Es schadet Ihrem Code sicherlich nicht, mehrere Aufrufe von quoteName() und quote() auszuführen, aber Ihr Code ist kürzer und daher ohne sie einfacher zu lesen.
  4. Verwenden Sie $query->dump(), um zu überprüfen, ob Ihre generierte Abfrage genau das ist, was Sie erstellen möchten.
  5. Verwenden Sie loadResult(), wenn Sie nur auf eine einzelne Spalte in der ersten Zeile einer Ergebnismenge zugreifen möchten.
  6. Es ist oft nützlich zu überprüfen, ob keine Zeilen in der Ergebnismenge zurückgegeben wurden. Die Überprüfung auf ein "falsches" Ergebnis mit ! (Siehe mein Snippet unten, in dem ich den Ergebniswert im selben Schritt deklariere und überprüfe) ist oft eine sinnvolle Einbeziehung.
  7. Die Verwendung eines try{}catch{} - Blocks ist eine schnelle und einfache Methode zum Debuggen Ihres Codes (im Vergleich zum Aktivieren der globalen Fehlerberichterstattung und zum Scrollen und Scrollen, um die Abfrage zu finden, die Sie tatsächlich zu debuggen versuchen). JFactory::getApplication()->enqueueMessage() ist eine großartige Möglichkeit, die Diagnose- und Fehlerinformationen zusammenzustellen, da sie oben auf Ihrer Seite in einem bootstrap Meldungsfeld angezeigt werden.

Mein empfohlenes Snippet:

try {
    $db = JFactory::getDbo();
    $user = JFactory::getUser();
    $query = $db->getQuery(true)
                ->select("Test_Percentile")
                ->from("#__calc_results")
                ->where("test_id = 1 AND user_id = $user->id");
    $db->setQuery($query);
    JFactory::getApplication()->enqueueMessage($query->dump(), 'info');
    if (!$perc = $db->loadResult()) {
        echo "<p>No Rows Found</p>";
    } else {
        echo "<p>$perc</p>";
    }
} catch (Exception $e) {
    JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error');
}

Es wäre mir ein Dorn im Auge, nicht zu erwähnen: Sie dürfen aus Sicherheitsgründen niemals Fragen oder Fehlermeldungen öffentlich anzeigen

Alternative Möglichkeiten zum Erstellen der WHERE-Klausel:

Die Wahrheit ist, dass es mehrere Möglichkeiten gibt, eine gültige WHERE -Klausel zu schreiben, die mit der Abfrageerstellungsmethode von Joomla zwei Bedingungen enthält (über die perfekte gültige einzelne Zeichenfolge hinaus).

where() x2:

->where("test_id = 1")
->where("user_id = $user->id");
// WHERE test_id = 1 AND user_id = 75

where() und andWhere(): (Ich rate nicht zu unnötigen Klammern)

->where("test_id = 1")
->andWhere("user_id = $user->id");
// WHERE (test_id = 1) AND (user_id = 75)

where() mit einer Reihe von Bedingungen:

->where(array("test_id = 1", "user_id = $user->id"));
// WHERE test_id = 1 AND user_id = 75
1
mickmackusa