Benutzer mit den meisten Antworten
Escapen von Sonderzeichen

Frage
-
Hallo zusammen,
ich verwende ADO.NET und den Typ SqlParameter, für die Übergabe von Werten in die Where-Bedingung.
Wird nach einem Begriff mit einem Sonderzeichen gesucht, z.B. nach einer eMail mit einem Unterstrich (first1_last1@test.de), müsste dafür gesorgt werden, dass dieser escaped wird.
Ist meine Annahme korrekt, dass dies nicht explizit notwendig ist, wenn der Wert (first1_last1@test.de) in das SqlCommand durch einen SqlParameter übergeben wird?
Meine Vermutung ist, dass ADO.NET für SqlServer so programmiert ist, dass es solche Fälle bereits berücksichtigt.
Ist diese Annahme korrekt?
Viele Grüße,
Christian
Antworten
-
Hallo Christian,
die Value Property deines SqlParameters ist falsch.
first1!_last1@test.de% ESCAPE '!'
resultiert letztendlich in folgender WHERE Klausel:
... WHERE Spaltenname LIKE 'first1!_last1@test.de% ESCAPE ''!'''
Es wird also explizit nach dem Inhalt:
first1!_last1@test.de% ESCAPE '!'
gesucht. Sprich, nach deiner Emailadresse müsste im Spaltenwert noch " ESCAPE '!'" vorkommen, was natürlich nicht der Fall ist.
Du musst ESCAPE '!' aus dem Parameterwert rausholen und in den CommandText schreiben.
<SqlCommand>.CommandText = "SELECT id FROM MyTable WHERE mail LIKE @mail_1 ESCAPE '!'"
Und im Wert des Parameters darf dann eben nur:
first1!_last1@test.de%
stehen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Donnerstag, 27. Oktober 2016 16:27
- Als Antwort markiert ChristianHavelDE Montag, 31. Oktober 2016 12:02
Alle Antworten
-
Hallo Christian,
Ich wüsste nicht, das ADO.NET oder andere Datenprovider da klammheimlich im Hintergrund etwas abändert.
Das escapen von Zeichen musst Du selbst vornehmen, wobei es eh nur zum Tragen kommt, wenn Du den LIKE Operator verwendest; bei = ist sind Wildcard-Zecihen eh egal.
Olaf Helper
[ Blog] [ Xing] [ MVP] -
Hallo Christian,
Kurz: Ja, ADO.NET ist richtig programmiert.
Lang: Du suchst Probleme, wo es keine gibt.
@ wird als Präfix nur bei Variablennamen verwendet. Innerhalb einer Zeichenfolge hat es keinerlei besondere Bedeutung. (Selbst wenn es eine Variable gleichen Namens geben würde.)
Bei einem SqlParameter, der eine Zeichenfolge übergibt (wie SqlDbType.NVarChar), wird die übergebene Zeichenfolge in Anführungszeichen gesetzt und ggf. dort enthaltene Anführungszeichen verdoppelt. Für Unicode Daten wird das Präfix "N" vorangestellt.
Wobei letzteres eine abstrakte Darstellung ist, intern wird das TDS Protokoll verwendet.
Gruß Elmar
- Bearbeitet Elmar BoyeEditor Mittwoch, 26. Oktober 2016 16:41 TDS
-
Hallo,
ich vermute, der OP meint die Suche nach _, was in einer LIKE Abfrage ja einem einzelnen beliebigen Zeichen entspricht.
Spalte LIKE 'first1_last1@test.de'
würde daher ja auch first1Xlast1@test.de finden.
@OP: In deinem Fall müsstest Du das so umwandeln:
Spalte LIKE 'first1[_]last1@test.de'
wobei Du dann auch gleich mit einem normalen Stringvergleich arbeiten kannst
Spalte = 'first1_last1@test.de'
und dabei dann keine Probleme mit dem Unterstrich, Prozentzeichen, usw. hast.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Stefan,
da dürftest Du Recht haben - ich hab den "_" schlicht und einfach übersehen.
@Christian: In der Verwendung als Platzhalter bei den Befehlen, die sie unterstützen (LIKE ,PATINDEX) müssen sie dann tatsächlich manuell maskiert werden, siehe z. B.: LIKE, da eine Analyse der SQL Anweisung von keinem Treiber vorgenommen wird.
Gruß Elmar
-
Hallo zusammen.
Ein herzliches Dankeschön an euch alle :-)
In dem betroffenen Programmcode wird aktuell aus first1_last1@test.de der Wert first1!_last1@test.de ESCAPE '!'% generiert.
Diese Wandlung wird vorgenommen für diese Sonderzeichen:
var _likeWildcards = new List<string>{"%", "_", "[", "]", "^"};
Ist es korrekt, wenn ich dafür sorge, dass alle _likeWildCards wie folgt maskiert werden?
- % => [%]
- _ => [_]
- [ => [[]
- ] => []]
- ^ => [^]
Viele Grüße,
Christian - % => [%]
-
Hallo Christian,
Der generierte Programmcode ist korrekt und ich würde bei LIKE dabei bleiben und das ESCAPE Zeichen (im Ausdruck "%") nutzen. Denn eine Maskierung mit "[]" hat u. U. Seiteneffekte, wie bei [^], das gleichzeitig ein Platzhalter ist:
CREATE TABLE Tabelle(Spalte varchar(40)); INSERT INTO Tabelle(Spalte) VALUES ('abc'), ('[abc]'), ('\abc'), ('^abc'); GO -- nur ^abc SELECT Spalte FROM Tabelle WHERE Spalte LIKE '\^%' ESCAPE '\'; -- alle ausser ^abc SELECT Spalte FROM Tabelle WHERE Spalte LIKE '[^\^]%' ESCAPE '\'; -- alle SELECT Spalte FROM Tabelle WHERE Spalte LIKE '[^]%'; -- alle SELECT Spalte FROM Tabelle WHERE Spalte LIKE '[^^]%'; -- keine SELECT Spalte FROM Tabelle WHERE Spalte LIKE '[^[^]]%';
Verwendet ihr auch PATINDEX sieht es anders aus, da gibt es leider kein ESCAPE.
Gruß Elmar
-
Hallo Elmar,
wenn ich im SSM eine Abfrage mit folgender Bedingung absetze, erhalte ich keinen Treffer:
where mail like 'first1!_last1@test.de ESCAPE ''!''%'
Diese Filterbedingung liefert einen Treffer:
where mail like 'first1[_]last1@test.de'
In der Tabelle steht
first1_last1@test.deWo ist denn bitte der Fehler bei der ersten Bedingung?
Viele Grüße,
Christian -
Hallo Christian,
bei der ersten sind Anführungszeichen enthalten - wobei ich nicht weiß, ob sie aus dem Kopieren von Code resultieren.
ESCAPE ist ein Schlüsselwort und muss außerhalb der Zeichenkette stehen und von einer Zeichenkette mit einem Zeichen gefolgt sein:
Funktionieren täte die "korrekte" Variante:
LIKE 'first1!_last1@test.de' ESCAPE '!'
Gruß Elmar
-
Hallo Christian,
ja, der Ausdruck ist falsch. Das Prozentzeichen soll ja, wenn Du LIKE verwendest, angeben, dass nach der Zeichenfolge x beliebige Zeichen folgen dürfen.
Du hättest das aber relativ schnell auch selbst gemerkt, wenn Du diese WHERE Klausel mal im SSMS probier hättest. Das kommt dann
Falsche Syntax in der Nähe von '%'.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Stefan,
ich nutze die SqlParameter. Dessen Value Property zeigt mir diesen Wert:
first1!_last1@test.de% ESCAPE '!'
Er trägt den ParameterName '@mail_1'
Der erstellte CommandText:
SELECT id FROM MyTable WHERE mail LIKE @mail_1
Warum findet er nichts?
Viele Grüße,
Christian
-
Hallo Christian,
die Value Property deines SqlParameters ist falsch.
first1!_last1@test.de% ESCAPE '!'
resultiert letztendlich in folgender WHERE Klausel:
... WHERE Spaltenname LIKE 'first1!_last1@test.de% ESCAPE ''!'''
Es wird also explizit nach dem Inhalt:
first1!_last1@test.de% ESCAPE '!'
gesucht. Sprich, nach deiner Emailadresse müsste im Spaltenwert noch " ESCAPE '!'" vorkommen, was natürlich nicht der Fall ist.
Du musst ESCAPE '!' aus dem Parameterwert rausholen und in den CommandText schreiben.
<SqlCommand>.CommandText = "SELECT id FROM MyTable WHERE mail LIKE @mail_1 ESCAPE '!'"
Und im Wert des Parameters darf dann eben nur:
first1!_last1@test.de%
stehen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Donnerstag, 27. Oktober 2016 16:27
- Als Antwort markiert ChristianHavelDE Montag, 31. Oktober 2016 12:02