strstr/LIKE - andersrum

klamm

Chef
Teammitglied
ID: 20876
L
20 April 2006
13.678
1.389
Ich steh grad aufm Schlauch.

Ich habe in der DB x Einträge (Needle) und will einen User-Parameter (Haystack) prüfen, ob Einträge aus der DB darin vorkommen. In PHP würde das mir strstr() gehen.
PHP:
foreach($db_entry as $needle)
   if(strstr($user_param, $needle)!="") return true;
Jetzt das Ganze in SQL. "LIKE" tut das ja - nur falschrum.
Da könnte ich nur sowas prüfen "where db_entry LIKE '%$user_param%'".
Ich brauchs jedoch grad andersrum. Any Ideas außer in PHP Durchlaufen? :-?
 
Hm müsste im LIKE-Teil nicht das "field" noch escaped werden, also % und _ ?
Sonst findet er ja nen Match auf $beliebig vs. '%'.field_mit_%.'%' = '%%%'.
 
Klar, wenn du zwischen den %....% - also bei dir im field - noch LIKE-Sonderzeichen hast, musst du die escapen.

(Nur so grundsätzlich - ich bin ja kein Performance-Meister -, aber schreit das nicht nach ner Volltextsuche? MATCH ... AGAINST...?)
 
Klar, wenn du zwischen den %....% - also bei dir im field - noch LIKE-Sonderzeichen hast, musst du die escapen.
Was ich aber bei dieser Variante auch via SQL on the fly machen müsste (wie? - mit string OPs?) - was IMHO sämtliche Index-Nutzung zunichte machen würde. Oder halt direkt die DB-Einträge escaped reinschreiben beim insert ... is glaub einfacher. "Andersrum" wurde halt immer die Usereingabe escaped, das mach ich ja sowieso standardmäßig. So rum muss man aber irgendwie krüpplig denken. :ugly:

Volltext lohnt hier nicht.
Es geht um Zeichenketten mit <100 Zeichen ...

Edit:
Und Match/Against arbeitet gar nicht so trivial wie man denkt. Führt oft zu ungewollten Ergebnissen bzw. behandelt man diese falsch wenn man denkt, LIKE einfach durch MATCH/AGAINST ersetzen zu können.
 
also bei DB2 for z/OS ist rechts von einem LIKE keine Spalte, sondern nur ein Ausdruck möglich. Ich weiss nicht, ob das bei mySQL anders ist.
Versuch doch mal so einen Ansatz:

WHERE REPLACE ( $user_parm , spalte , 'xxxxx' ) = $user_parm ...

also ersetze innerhalb des user_parm den gesuchten Ausdruck durch was anderes und wenn der ursprüngliche Inhalt noch da ist, wurde der gesuchte Ausdruck nicht gefunden


oder funktioniert sogar auch

WHERE INSTR($user_parm , spalte ) > 0
 
Zuletzt bearbeitet:
WHERE REPLACE ( spalte , $user_parm , 'xxxxx' ) = spalte
Also in mySQL funzt es andersrum, was ich auch zuerst nicht dachte. 8O
Habs jetzt so laufen.

REPLACE ist ein interessanter Ansatz. Ich fürchte nur, dass das nicht effizient performed ... da kann mans auch gleich in PHP holen und dort "rechnen", wenns nicht grad Millionen Einträge sind.
 
Was ich aber bei dieser Variante auch via SQL on the fly machen müsste (wie? - mit string OPs?)
Jo, 2x REPLACE() müsstest du dann wohl verwenden.

Effizient klingt das ganze Vorhaben schon ned. Wie ich Post #1 gelesen hab, dachte ich zuerst an einen Verstoß gegen 1NF.
 
naja,
$content LIKE '%' !! spalte !! '%'
dürfte auch nicht gerade performant sein, weil ein Index auch nicht genutzt werden kann ...
 
naja,
$content LIKE '%' !! spalte !! '%'
dürfte auch nicht gerade performant sein, weil ein Index auch nicht genutzt werden kann ...
Richtig.
Dachte jetzt eher an die zusätzlichen String-OPs ...

Muss mal benchmarken ob PHP nicht schneller is wenn ich mir das LIKE dafür komplett sparen kann. So viele Einträge sinds ja ned (<1000).

WHERE INSTR($user_parm , spalte ) > 0
Ui, jap. Arbeitet intern aber wie LIKE hab ich das Gefühl.
Ist exakt genauso schnell (langsam).
Aber gedanklich das, was ich suchte (siehe Post1/PHP). 8)
 
Wenn du den LIKE weiter verfolgen möchtest, dann überlege auch, ob du das % davor und danach nicht gleich in den String mit aufnimmst, dann sparst Du Dir beim Vergleich die CONCATs

Funktioniert im MySQL so ein Vergleich ( sorry, ich komme aus dem z/OS Umfeld, da geht manches etwas anders )

SELECT '1' FROM
TABLE ( $user_parm usereingabe) A JOIN blacklist_table B
ON A.usereingabe like B.verbotenes_wort ;

ist das Ergebnis ein NOTFOUND dann ist der Usereintrag in Ordnung
 
Wie wäre es denn die BadWord-Liste z.B. in APC oder memcached zu cachen?
Denn effizient wirst du die Operation mit MySQL nicht hinbekommen.