Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   LIKE auf mehrere Möglichkeiten anwenden (https://www.delphipraxis.net/67436-like-auf-mehrere-moeglichkeiten-anwenden.html)

faux 14. Apr 2006 11:40

Datenbank: MySQL • Version: 4.0 • Zugriff über: PHP 4.4.0 MySQL-Modul

LIKE auf mehrere Möglichkeiten anwenden
 
Hallo!

Ich habe auf einer Seite, welche Daten aus einer Datenbank anzeigt, eine Leiste mit den Links von A-Z, mit denen man die Suche nach Anfangsbuchstaben einschränken kann. Ich löse das dann einfach so:

SQL-Code:
SELECT *
  FROM page_series AS s, page_types AS t, page_publishers AS p
  WHERE s.type = t.id
    AND p.id = s.publisher
    AND serie LIKE 'B%cat%'
  ORDER BY serie ASC
Eigentlich kommts nur auf Zeile 5 an. In diesem Fall werden nur Einträge mit B beginnend angezeigt, klar.
Jetzt sollte es aber auch einen 0-9 Button und einen für Sonderzeichen geben.
Wie löse ich das, ohne alles mit OR zu verknüpfen?

Grüße
Faux

EDIT: Hab mal das Query etwas verlürzt, ist ja sinnlos sonst.

mkinzler 14. Apr 2006 11:45

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Ich würde einen parametrisierten Query anlegen:
SQL-Code:
SELECT s.id, serie, band, zusatz, t.type, author, p.publisher AS verlag, isbn, price, pages, publish_month, publish_year, notes
  FROM page_series AS s, page_types AS t, page_publishers AS p
  WHERE s.type = t.id
    AND p.id = s.publisher
    AND serie LIKE :such
  ORDER BY serie ASC
Den Parameter such mußt du beim aktivieren der Buttons nur entsprechend setzen:

Delphi-Quellcode:
query.ParamByName( 'such').value := '%B%';
Query.ExecSql;

faux 14. Apr 2006 11:52

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Danke für die Antwort, aber ich verstehe nur Bahnhof. :stupid:
Ich programmiere in PHP, was eigentlich egal sien müsste, da ich ja nur ein SQL-Query brauche.
Könntest du mir ev. den Link zur MySQL Doku für diese Parameter geben? Unter SELECT steht nichts und den Artikel zu LIKE finde ich auch gerade nichtmehr. :x

Grüße
Faux

marabu 14. Apr 2006 12:05

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Hallo Faux,

du schreibst von Präfixsuche und zeigst "B%cat%". Wenn es wirklich nur um eine Präfixsuche geht, dann geht es auch ohne LIKE und dessen schlechtes Laufzeitverhalten. Greife einfach das erste Zeichen per Substring() ab und machen einen Mengentest mit WHERE substring(...) IN ('0', '1', ...). Die genaue Syntax kannst du bestimmt in der Doku nachlesen.

Grüße vom marabu

mkinzler 14. Apr 2006 12:06

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Hallo faux,

In PHP bringt das mit den Parametern eh nicht so viel, da beim Klick auf einen Button sowieso ein Skript neu gestartet wird. Ich vestehe deine Frage nur nicht ganz. Es soll doch immer nur nach einem Anfangbuchstaben ( ich zähle nun Ziffern und Sonderzeichen auch dazu) sortiert werden oder? Dann brauchst du ja kein OR.
In PHP kannst du das aber auch anderst lösen verwende die Abfrage:

SQL-Code:
SELECT s.id, serie, band, zusatz, t.type, author, p.publisher AS verlag, isbn, price, pages, publish_month, publish_year, notes
  FROM page_series AS s, page_types AS t, page_publishers AS p
  WHERE s.type = t.id
    AND p.id = s.publisher
    AND serie LIKE ".$_POST['such']."%";
  ORDER BY serie ASC
und übergebe dem Skript den gesuchten Anfangsbuchstaben per POST/GET .

[Achtung: meine Lösung ist exemplarisch, da eigentlich eine Übgabe an ein Skript niemals ungeprüft verwendet werden sollte / SQL-Injection möglich]

faux 14. Apr 2006 12:14

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Also mein Problem liegt nicht an der PHP-Umsetzung sondern am SQL-Query:
Der User sucht nach cat. Also lautet das Query %cat%.
Da aber "cat" unter Umständen einige Hundert Suchergebnisse liefert, habe ich so eine Leiste eingebaut:
Code:
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Wenn der User auf "A" klickt, wird das Query so abgeändert: A%cat%, also nur die Suchergebnisse angezeigt, die mit A beginnen. Da gibts auch kein Problem.
Nur gibt es auch Suchergebnisse, welche nicht mit Buchstaben, sondern mit einer Ziffer oder einem Sonderzeichen beginnen. Wie bekomme ich diese jetzt? Ich will nicht 10 Buttons machen mit 1, 2, 3, ... sondern einen Button, der alle Einträge, welche mit einer Ziffer beginnen anzeigt.

Zitat:

Zitat von marabu
du schreibst von Präfixsuche und zeigst "B%cat%". Wenn es wirklich nur um eine Präfixsuche geht, dann geht es auch ohne LIKE und dessen schlechtes Laufzeitverhalten. Greife einfach das erste Zeichen per Substring() ab und machen einen Mengentest mit WHERE substring(...) IN ('0', '1', ...). Die genaue Syntax kannst du bestimmt in der Doku nachlesen.

Werde ich mal probieren.

Grüße
Faux

mkinzler 14. Apr 2006 12:23

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Jetzt habe auch ich verstanden, auf was du hinaus willst. Dann mußt du ja nur den Lösungsvorschlag von Achim mit einbeziehen und die Abfrage nach Anfangsziffern durh eine OR-Bedingung anhängen.

SQL-Code:
...
WHERE s.type = t.id
    AND p.id = s.publisher
    AND ((serie LIKE '%'.$_POST['cat']."%') OR ( substring (...) IN ( ".$_POST['begmit']."));
und übergibst dann cat und begmit in der Form: "'A'", oder bei Ziffern: "'0', '1', '2', ..."

faux 15. Apr 2006 10:48

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Zitat:

Zitat von mkinzler
SQL-Code:
...
WHERE s.type = t.id
    AND p.id = s.publisher
    AND ((serie LIKE '%".$_POST['cat']."%') OR ( substring (...) IN (".$_POST['begmit']."));

Müsste es nicht AND heißen?

SO gehts:
SQL-Code:
SELECT *
FROM page_series AS s, page_types AS t, page_publishers AS p
WHERE s.type = t.id
  AND p.id = s.publisher
  AND serie LIKE '%masken%'
  AND substring(serie,1,1) IN ('1','2','3','4','5','6','7','8','9','0')
ORDER BY serie, band ASC
Aber ist das AND von mir richtig, oder ein Denkfehler und dein OR stimmt?

Habe gerade eine noch einfachere Methode rausgefunden:
SQL-Code:
AND substring(serie,1,1) BETWEEN '0' AND '9'
Danke für die Hilfe!

Grüße
Faux

mkinzler 15. Apr 2006 11:11

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Stimmt es muß and heißen !

generic 16. Apr 2006 00:22

Re: LIKE auf mehrere Möglichkeiten anwenden
 
SQL-Code:
  AND serie LIKE ".$_POST['such']."%";
wer sowas benutzt braucht sich nicht zu wundern wenn die datenbank leer ist oder die seite defaced wird!

ACHTUNG SOLCHE KONSTRUKTE SIND UNSICHER!

jedes script kidde wird euch dort eine SQL injection machen.

bitte das hier mal durchlesen:
http://www.unixwiz.net/techtips/sql-injection.html

gruss

mkinzler 16. Apr 2006 07:28

Re: LIKE auf mehrere Möglichkeiten anwenden
 
@generic: Lese mal meinen Beitrag #5

yankee 16. Apr 2006 09:22

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Btw: statt LIKE kannst du auch REGEX verwenden. Und dann kannst du nach regulaeren Ausdruecken suchen. Das ganze ist wahrscheinlich ein bisschen langsamer (muesstes du mal ausprobieren) aber praktisch. Denn du kannst einfach nach
SQL-Code:
AND serie REGEX '/^\d/'
Suchen und bekommst nur alles, was mit einer Ziffer anfaengt. Mit regexen laesst sich natuerlich noch viel mehr anfangen :-).

faux 16. Apr 2006 10:45

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Zitat:

Zitat von generic
SQL-Code:
AND serie LIKE ".$_POST['such']."%";
wer sowas benutzt braucht sich nicht zu wundern wenn die datenbank leer ist oder die seite defaced wird!

Also dann kann ich ja froh sein, dass ich nicht dabei bin. ;)

Zitat:

Zitat von generic

Also so habe ich das noch nicht gesehen. Ich habe aber am Anfang meines Skriptes folgende Zeilen stehen:
Code:
[color=#800080]foreach[/color] ([color=#000080][i]$_GET[/i][/color] [color=#800080]as[/color] [color=#000080][i]$value[/i][/color])
{
  [color=#000080][i]$value[/i][/color] = mysql_real_escape_string([color=#000080][i]$value[/i][/color]);
}
Diese habe ich aber deswegen eingefügt, dass bei einer Eingabe von einem ' kein SQL-Fehler entsteht, an solche bösen Ideen habe ich noch garnicht gedacht. Aber so sollte das ganze doch auch sicher sein, oder?

:lol: Jetzt wo ihrs sagt: Ich machs dem Angreifer auch so einfach wie es nur geht. Ich stell ihm sogar das ganze Query zur Verfügung:

Code:
<!-- SQL: Query successful: '
  SELECT s.id, serie, band, zusatz, t.type, author, p.publisher AS verlag, isbn, price, pages, publish_month, publish_year, notes
  FROM page_series AS s, page_types AS t, page_publishers AS p
  WHERE s.type = t.id
    AND p.id = s.publisher
  ORDER BY serie, band ASC' -->
Seht euch mal den Quellcode an bitte: http://web575.servana.de/animeworld/series.php. Ist das unsicher, wenn ich hier jede SQL-Aktion ausgebe?
btw: Bin nur der Programmierer; für den Inhalt kann ich nicht haften. :mrgreen:

Grüße
Faux

yankee 16. Apr 2006 11:02

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Zitat:

Zitat von faux
Code:
[color=#800080]foreach[/color] ([color=#000080][i]$_GET[/i][/color] [color=#800080]as[/color] [color=#000080][i]$value[/i][/color])
{
  [color=#000080][i]$value[/i][/color] = mysql_real_escape_string([color=#000080][i]$value[/i][/color]);
}
Diese habe ich aber deswegen eingefügt, dass bei einer Eingabe von einem ' kein SQL-Fehler entsteht, an solche bösen Ideen habe ich noch garnicht gedacht. Aber so sollte das ganze doch auch sicher sein, oder?

Grüße
Faux

WAS???? Das funktioniert bei dir???
Du hast bestimmt nur magic-quotes aktiviert, die das fuer dich machen, denn deine foreach-schleife macht garnichts.
Denn in foreach($ar as $v) ist $v nur eine KOPIE der variable. Jede veranderung, die du da reinschreibst ist sofort wieder futsch!
Erst ab PHP5 kannst du statt $v auch eine Referenz verwenden (&$v). Dann kannst du auch aendern.

Siehe: http://us2.php.net/manual/en/control...es.foreach.php

Jelly 16. Apr 2006 11:36

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Also um die Performance noch bischen zu heben, würde ich erstmal all diese Konstrukte mit like, substring und regexp verwerfen, da die allesamt grottenlahm sind.

Im Fall wird doch lediglich nach Einträgen gesucht, die mit einem bestimmten Anfangsbuchstaben oder Anfangszeichenkette beginnen. (z.B. mit Buh)
Delphi-Quellcode:
... where serie >= 'Buh' and serie < 'Bui' ...
Einen schönen Index auf das Serie-Feld, und das Ganze wird um Ecken schneller sein.

yankee 16. Apr 2006 11:53

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Zitat:

Seht euch mal den Quellcode an bitte: http://web575.servana.de/animeworld/series.php. Ist das unsicher, wenn ich hier jede SQL-Aktion ausgebe?
Ja ist (soweit ich sehe) sicher. Wenn es nicht sicher waere, dann waere es auch nur Sicherheit powered by Verschleierung. Waere nicht gut.
Ich wuerde das am Ende aber trotzdem rausnehmen. Das ist irgendwie trafficverschwendung. Gut ist ja nicht viel aber wenn wir uns hier schon ueber jede Performancsteigerung streiten :-).
Du kannst dir ja eine Konstante DEBUGGING definieren, die du auf true oder false setzt. Danach kannst du dann soclhe Ausgaben machen.

DENK aber an deinen foreach-Fehler!

faux 16. Apr 2006 11:57

Re: LIKE auf mehrere Möglichkeiten anwenden
 
@yankee:
Äähm.. :oops:
Das habe ich natürlich nicht dort stehen. :roll:
Ich habe das dort stehen:
Code:
foreach ($_GET as $name => $value)
{
  $_SQL[$name] = $sql->escape($value);
}
Und in jeder SQL-Aktion benutze ich anstatt von $_GET dann $_SQL.
Den vorherigen Code habe ich (wieso auch immer) nur schnell mal hier her geschrieben, weil ich gerade keine Datei offen hatte. :wall:

btw: Ja, MAGIC_QUOTES sind aktiv (zumindest hat beim Aufruf von seite?foo=bar'bar die Variable $_GET['foo'] den Wert bar\'bar. Weiß nicht ob das die MAGIC_QUOTES sind.).

Ja, das mit der DEBUG-Konstante hab ich auch so gelöst.

Grüße
Faux

yankee 16. Apr 2006 12:09

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Wenn du magic-quotes anhast und mysql-escape machst, dann encapsed du die ' aber glaube ich doppelt. Bin mir allerdings jetzt gerade nicht so sicher. Denn wenn du magic0quotes anhastm dann brauchst du mysql_escape nurnoch fuer so ein paar komische werte, was aber kein Sicherheitsrisiko mehr darstellt.
*hicks* sry, wenn es sich schwer lesen lest, ich bin to muede und geh jetzt auch mal ins Bett :-)...

faux 16. Apr 2006 19:42

Re: LIKE auf mehrere Möglichkeiten anwenden
 
Zitat:

Zitat von yankee
Wenn du magic-quotes anhast und mysql-escape machst, dann encapsed du die ' aber glaube ich doppelt.

Habe ich auch bemerkt. ;) Aber nachdem sowieso keine ' in Strings vorkommen sollen, is mir das egal. :P

Grüße
Faux


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz