Autor Beitrag
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 18.08.15 23:42 
Moin!

Ich versuche grade in MySQL nach einem Backslash in einem Textfeld zu suchen, also sowas hier:
ausblenden 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:
ausblenden 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

_________________
There are 10 types of people - those who understand binary and those who don´t.
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 429
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Mi 19.08.15 07:12 
Eine Lösung mit LIKE hab ich nicht, aber mit instr funktioniert es:

ausblenden 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...

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
Nersgatt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Mi 19.08.15 07:15 
So klappts auch mit dem Nachbarn LIKE:

ausblenden SQL-Anweisung
1:
2:
select id from tmp
where textfeld like '%\%' escape '|';

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 19.08.15 15:32 
Moin!

Schonmal Danke für´s Mitdenken! :beer:

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
Kann es sein, daß Du Komponenten verwendest,
Nein, kein Delphi, keine Komponenten. Nackiges SQL direkt in phpMyAdmin.

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
"Auch vier Backslashes finden das gewünschte" - wie meinst Du das? mit 4 mal \ wird dann wirklich der
Backslash gefunden?
Jap. ;)


user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Eine Lösung mit LIKE hab ich nicht, aber mit instr funktioniert es:
Spannend! :P

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
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

_________________
There are 10 types of people - those who understand binary and those who don´t.
Nersgatt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Mi 19.08.15 16:41 
Ich hab mir mal die Doku angeschaut zu dem Thema: dev.mysql.com/doc/re...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:

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)

Für diesen Beitrag haben gedankt: Narses
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: 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 (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.

Für diesen Beitrag haben gedankt: Narses, Nersgatt