Entwickler-Ecke
Datenbanken - Mit LIKE nach Backslash im Text suchen
Narses - Di 18.08.15 23:42
Titel: Mit LIKE nach Backslash im Text suchen
Moin!
Ich versuche grade in MySQL nach einem Backslash in einem Textfeld zu suchen, also sowas hier:
SQL-Anweisung
1:
| SELECT * FROM `objects` WHERE `obj_caption` LIKE '%\\%' |
Das klappt aber nicht: es werden Texte gefunden, die ein Prozent-Zeichen enthalten. :? :gruebel:
Wenn ich da noch einen Backslash mehr rein tue, dann klappt das:
SQL-Anweisung
1:
| SELECT * FROM `objects` WHERE `obj_caption` LIKE '%\\\%' |
:shock: Auch vier Backslashes finden das gewünschte, ab 5 nicht mehr. :suspect:
Kann mir das mal eben einer erklären? :nixweiss: :nut: Bei 3 Backslashes suche ich nach einem Text, der auf "\%" endet (\\ -> \, \% -> %, escaping eben)... oder?
cu
Narses
mandras - Mi 19.08.15 00:37
Kann es sein, daß Du Komponenten verwendest, die erst einmal ein "\\" durch ein "\" ersetzen?
Damit wäre erklärt, daß bei zwei \ das Prozent gefunden wird.
"Auch vier Backslashes finden das gewünschte" - wie meinst Du das? mit 4 mal \ wird dann wirklich der
Backslash gefunden?
Falls ja _vermute_ ich wieder: in erster Stufe wird aus "\\\\" ein "\\", die MySQL was auch immer machen daraus dann das wirkliche "\".
Ist Kaffesatzdeuterei meinerseits, ich weiß... Ich kenne ja nicht Deinen Zugriff, ob über Parameter einer Query etc.
Ok, laut Deines Code-Schnippsels ohne Parameter. Aber man weiß ja nie
LG
Andreas
Nersgatt - Mi 19.08.15 07:12
Eine Lösung mit LIKE hab ich nicht, aber mit instr funktioniert es:
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| create temporary table tmp ( id int, textfeld varchar(10) ); insert into tmp values (1, 'bla'); insert into tmp values (2, 'blubb'); insert into tmp values (3, 'bla \\ blubb');
select id from tmp where instr(textfeld, '\\') > 0; drop temporary table tmp; |
Performant ist das sicher nicht...
Nersgatt - Mi 19.08.15 07:15
So klappts auch mit
dem Nachbarn LIKE:
SQL-Anweisung
1: 2:
| select id from tmp where textfeld like '%\%' escape '|'; |
Narses - Mi 19.08.15 15:32
Moin!
Schonmal Danke für´s Mitdenken! :beer:
mandras hat folgendes geschrieben : |
Kann es sein, daß Du Komponenten verwendest, |
Nein, kein Delphi, keine Komponenten. Nackiges SQL direkt in phpMyAdmin.
mandras hat folgendes geschrieben : |
"Auch vier Backslashes finden das gewünschte" - wie meinst Du das? mit 4 mal \ wird dann wirklich der
Backslash gefunden? |
Jap. ;)
Nersgatt hat folgendes geschrieben : |
Eine Lösung mit LIKE hab ich nicht, aber mit instr funktioniert es: |
Spannend! :P
Nersgatt hat folgendes geschrieben : |
So klappts auch mit dem Nachbarn LIKE: |
:nut: Aber eine Lösung, Respekt! :zustimm:
Erklärt allerdings immer noch nicht, was da passiert... :gruebel:
cu
Narses
Nersgatt - Mi 19.08.15 16:41
Ich hab mir mal die Doku angeschaut zu dem Thema:
https://dev.mysql.com/doc/refman/5.0/en/string-literals.html
Ich hoffe, es wenigstens teilweise erklären zu können.
Ich gehe mal von dem "%\\% aus:
Hier steht
Zitat: |
The “\%” and “\_” sequences are used to search for literal instances of “%” and “_” in pattern-matching contexts where they would otherwise be interpreted as wildcard characters. |
Das hieße, durch das 2. Backslash wird dafür gesorgt, dass das 2. % nicht mehr als Wildcard, sondern als Literal benutzt wird. Zur besseren Lesbarkeit stelle ich ab hier das letzte %-Literal mal als § dar und das %-Wildcard als %. Damit wäre meinem Verständnis nach das 2. Bashslash "verbraucht". Nun haben wir also noch "%\§". Weiter vorne steht:
Zitat: |
MySQL recognizes the escape sequences shown in Table 9.1, “Special Character Escape Sequences”. For all other escape sequences, backslash is ignored. |
Da das § (%-Literal) nicht in Tabelle 9.1 als Special Escape Sequence aufgeführt ist, komme ich zu dem Schluss, dass hier das \ ignoriert wird. Somit wird aus "%\§" -> "%§" Somit sucht "%\\%" nur nach Strings, die mit dem Prozentzeichen enden (das erste % ist weiterhin als Wildcard zu sehen). :eyecrazy:
Meine Vermutung bedingt, dass MySql den String von hinten nach vorn durchsucht... :nixweiss:
Die Sache mit den 3 und 4 Backslashes sind mir aber noch zu hoch... :suspect:
Marc. - Mi 19.08.15 17:48
Zitat: |
Because MySQL uses C escape syntax in strings (for example, “\n” to represent a newline character), you must double any “\” that you use in LIKE strings. For example, to search for “\n”, specify it as “\\n”. To search for “\”, specify it as “\\\\”; this is because the backslashes are stripped once by the parser and again when the pattern match is made, leaving a single backslash to be matched against. |
Quelle:
MySQL Ref [
https://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like] (Hervorhebung von mir)
Sprich: Im ersten Schritt cancelt der Parser jedes zweite Backslash und dann geschieht das eigentliche Parsing:
\\%
\rightarrow \%
\rightarrow %
\\\%
\rightarrow \\%
\rightarrow \
\\\\%
\rightarrow \\%
\rightarrow \
\\\\\%
\rightarrow \\\%
\rightarrow \%
So mein Verständnis.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!