Gibt es ein T-SQL-Äquivalent zu den Mustern [0-9]
und [a-z]
, mit dem ich Werte aus einer Spalte abrufen kann, die Interpunktion enthält?
Zum Beispiel:
Create Table #Test
(
Value VarChar(10)
)
Insert Into #Test
Values ('123a'), ('456b'), ('12ABC'),('AB!23'),('C?D789')
Select *
From #Test
Where Value like '[0-9][0-9][0-9][a-z]'
Dies würde Werte zurückgeben, bei denen die ersten 3 Zeichen Zahlen zwischen 0 und 9 sind und das letzte Zeichen ein Buchstabe zwischen a und z ist, also Dinge wie 123a
und zurückgeben 456b
würde, aber keinen Wert von zurückgeben würde 12ABC
.
Ich möchte wissen, ob es ein Äquivalent für Interpunktion gibt, wie [0-9]
für Zahlen und [a-z]
für Buchstaben, damit es zurückkehrt AB!23
und C?D789
?
Wenn ich einen regulären Ausdruck verwenden könnte, könnte ich den Ausdruck verwenden ^[a-zA-Z0-9]*$
, um alphanumerische Zeichen in einer Zeichenfolge abzugleichen.
Where Value like '^[a-zA-Z0-9]*$'
Gibt es dafür ein SQL-Äquivalent?
Ich kenne solche Dinge, die in RegEx ausgeführt werden können, aber ich benötige sie in T-SQL. Ich kann keine benutzerdefinierten Assemblys auf diesen Server laden und kann daher keine regulären Ausdrücke verwenden.
Die reale Spalte ist varchar (200) . Die Sortierung lautet Latin1_General_CI_AS. Ich verwende SQL Server 2012 Standard Edition.
Antworten:
Die größte Schwierigkeit, eine genaue Lösung zu finden, besteht darin, genau zu definieren , welche Zeichen eingeschlossen (oder ausgeschlossen) werden sollen, je nachdem, welche Richtung für die Operation sinnvoller ist. Bedeutung:
VARCHAR
/ ASCII-Daten oderNVARCHAR
/ Unicode-Daten? Die Liste der Satzzeichen für ASCII-Daten hängt von der Codepage ab, die wiederum von der Sortierung abhängt. ( In dieser Frage beschäftigen wir uns mit ASCII-Daten ).Latin1_General_CI_AS
).
,,
,;
,:
, usw.) oder bedeutet es , nicht-alphanumerische Zeichen?¢
,£
,¥
, etc?©
und™
?Â
,É
,Ñ
,ß
,Þ
enthalten?Æ
æ
Um die Klarheit hinsichtlich des erwarteten Verhaltens zu verbessern, werden in der folgenden Abfrage alle 256 Zeichen des Latin1-Zeichensatzes (dh Code Seite 1252) und die Funktionsweise von zwei Varianten der von @ Shaneis vorgeschlagenen Lösung angezeigt . Das erste Feld (gekennzeichnet als
Latin1_General_CI_AS
) zeigt dieLIKE
von @Shaneis vorgeschlagene Klausel (zum Zeitpunkt dieses Schreibens) und das zweite Feld (gekennzeichnet alsLatin1_General_100_BIN2
) zeigt eine Modifikation, bei der ich die Kollatierung überschrieben habe, um eine binäre anzugeben (dh eine Kollatierung, die mit endet_BIN2
;_BIN
Sortierungen sind veraltet, verwenden Sie sie also nicht, wenn Sie Zugriff auf die_BIN2
Versionen haben. Dies bedeutete, dass ich auch denA-Z
Bereich hinzufügen musste, um Großbuchstaben herauszufiltern, da bei der aktuellen Sortierung die Groß- und Kleinschreibung nicht berücksichtigt wird:AKTUALISIEREN
Es sollte erwähnt werden, dass WENN man wirklich versucht, Zeichen zu finden, die als "Interpunktion" (und nicht als "Währungssymbol", "mathematisches Symbol" usw.) klassifiziert sind, und WENN es nicht verboten ist, SQLCLR zu verwenden / einen Benutzer zu laden Assembly (SQLCLR wurde mit SQL Server 2005 eingeführt, und ich habe noch keinen guten Grund gefunden, dies nicht zuzulassen, insbesondere da Azure SQL Database V12
SAFE
Assemblies unterstützt ). Dann können Sie reguläre Ausdrücke verwenden, jedoch nicht aus dem Grund, den die meisten Benutzer verwenden würde raten.Anstatt reguläre Ausdrücke zu verwenden, um einen funktionaleren Zeichenbereich zu erstellen, oder sogar etwas wie
\w
(dh ein "Wort" -Zeichen) zu verwenden, können Sie die Unicode-Kategorie der Zeichen angeben, nach denen Sie filtern möchten, und es gibt mehrere definierte Kategorien ::https://www.regular-expressions.info/unicode.html#category
Sie können sogar den Unicode-Block angeben, nach dem gefiltert werden soll, z. B. "InBengali" oder "InDingbats" oder "InOptical_Character_Recognition" usw.:
https://www.regular-expressions.info/unicode.html#block
Es gibt zahlreiche Beispiele zum Erstellen von RegEx-Funktionen für SQL Server (obwohl die meisten Beispiele nicht den bewährten Methoden von SQLCLR entsprechen), oder Sie können die kostenlose Version der SQL # -Bibliothek (die ich erstellt habe) herunterladen und die skalare RegEx_IsMatch- Funktion wie folgt verwenden ::
Der
\p{P}
Ausdruck bedeutet\p
= Unicode-Kategorie und{P}
= alle Interpunktion (im Gegensatz zu einer bestimmten Art von Interpunktion, wie z. B. "Connector-Interpunktion"). UND, die Kategorie "Interpunktion" umfasst alle Interpunktionen in allen Sprachen! Sie können die vollständige Liste auf der Unicode.org-Website über den folgenden Link anzeigen (derzeit befinden sich 717 Codepunkte in dieser Kategorie):http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AGeneral_Category%3DPunctuation%3A%5D
Eine aktualisierte Version der Testabfrage oben gezeigt, einschließlich eines anderen Feld , das verwendet SQL # .RegEx_IsMatch mit
\p{P}
, und die Ergebnisse aller drei Tests für alle 256 Zeichen von Codepage 1252 (dh Latin1_General) hat auf PasteBin.com bei gepostet:T-SQL-Abfrage und Ergebnisse zum Filtern von Zeichentypen
UPDATE
Folgendes wurde in der zugehörigen Diskussion erwähnt:
In diesem Fall:
Der Latin1-Zeichensatz / die Codepage enthält 11 nicht englische Zeichen, die nicht mit dem
a-z
Bereich übereinstimmen . Sie sind :ð Ð Þ þ œ Œ š Š ž Ž Ÿ
. Diese müssen dem Platzhalter hinzugefügt werden, und obwohl dies im Moment nicht erforderlich ist, würde es nicht schaden, sie hinzuzufügen,A-Z
damit das Muster bei einer Sortierung mit Groß- und Kleinschreibung genauso gut funktioniert. Das Endergebnis ist:LIKE '%[^a-zA-Z0-9ðÐÞþœŒšŠžŽŸ]%'
In Anbetracht der Tatsache, dass diese Daten "Hotelnamen aus der ganzen Welt" enthalten können, würde ich dringend empfehlen, den Datentyp der Spalte so zu ändern
NVARCHAR
, dass Sie alle Zeichen aus allen Sprachen speichern können. Wenn Sie diesVARCHAR
beibehalten, besteht ein sehr hohes Risiko für Datenverluste, da Sie nur die lateinischen Sprachen darstellen können und nicht einmal vollständig für diejenigen, die die sechs zusätzlichen Unicode-Kategorien enthalten, die zusätzliche lateinische Zeichen enthalten.quelle
Ich vereinfache dies möglicherweise ein wenig, aber wenn wir sagen, dass beim Entfernen alphanumerischer Werte nur noch Interpunktion übrig bleibt, wird im Folgenden nach Zeichenfolgen gesucht, die nicht alphanumerische Zeichen enthalten.
quelle