Ich habe die folgende Testtabelle in SQL Server 2005:
CREATE TABLE [dbo].[TestTable]
(
[ID] [int] NOT NULL,
[TestField] [varchar](100) NOT NULL
)
Bestückt mit:
INSERT INTO TestTable (ID, TestField) VALUES (1, 'A value'); -- Len = 7
INSERT INTO TestTable (ID, TestField) VALUES (2, 'Another value '); -- Len = 13 + 6 spaces
Wenn ich versuche, die Länge von TestField mit der SQL Server LEN () -Funktion zu ermitteln, werden die nachfolgenden Leerzeichen nicht gezählt - z.
-- Note: Also results the grid view of TestField do not show trailing spaces (SQL Server 2005).
SELECT
ID,
TestField,
LEN(TestField) As LenOfTestField, -- Does not include trailing spaces
FROM
TestTable
Wie füge ich die nachgestellten Leerzeichen in das Längenergebnis ein?
sql-server
Jason Snelders
quelle
quelle
Antworten:
Dies wird von Microsoft in MSDN unter http://msdn.microsoft.com/en-us/library/ms190329(SQL.90).aspx klar dokumentiert , wobei LEN "die Anzahl der Zeichen des angegebenen Zeichenfolgenausdrucks ausschließt, ausgenommen nachgestellte Leerzeichen ". Es ist jedoch ein leicht zu übersehendes Detail, wenn Sie nicht vorsichtig sind.
Sie müssen stattdessen die DATALENGTH-Funktion verwenden - siehe http://msdn.microsoft.com/en-us/library/ms173486(SQL.90).aspx - die "die Anzahl der Bytes zurückgibt, die zur Darstellung eines Ausdrucks verwendet werden".
Beispiel:
quelle
DATALENGTH
Sie müssen das Ergebnis auch durch 2 teilen, wenn der getestete Ausdruck ein breiter Zeichentyp ist (Unicode; nchar, nvarchar oder ntext), da das Ergebnis in Bytes und nicht in Zeichen angegeben ist .varchar
etc. kann dies kollationsabhängig sein und nicht einmal eine direkte Division durch 2 ist zuverlässig. Siehe Beispiel hierLEN(REPLACE(expr, ' ', '_'))
. Dies sollte mitvarchar
undnvarchar
und Zeichenfolgen funktionieren, die spezielle Unicode-Steuerzeichen enthalten.DATALENGTH()
sollte nicht als alternative Methode zum Zählen von Zeichen angesehen werden, da Bytes anstelle von Zeichen gezählt werden. Dies ist wichtig, wenn dieselbe Zeichenfolge inVARCHAR
/ dargestellt wirdNVARCHAR
.Sie können diesen Trick verwenden:
LEN (Str + 'x') - 1
quelle
Ich benutze diese Methode:
Ich bevorzuge dies gegenüber DATALENGTH, da dies mit verschiedenen Datentypen funktioniert, und ich bevorzuge es gegenüber dem Hinzufügen eines Zeichens am Ende, da Sie sich nicht um den Randfall kümmern müssen, in dem Ihre Zeichenfolge bereits die maximale Länge hat.
Hinweis: Ich würde die Leistung testen, bevor ich sie mit einem sehr großen Datensatz verwende. obwohl ich es gerade gegen 2M Zeilen getestet habe und es ohne REPLACE nicht langsamer als LEN war ...
quelle
Sie veranlassen jemanden, eine SQL Server-Erweiterungsanforderung / einen Fehlerbericht einzureichen, da fast alle hier aufgeführten Problemumgehungen für dieses erstaunlich einfache Problem Mängel aufweisen oder ineffizient sind. Dies scheint in SQL Server 2012 immer noch der Fall zu sein. Die Funktion zum automatischen Trimmen stammt möglicherweise aus ANSI / ISO SQL-92, aber es scheint einige Lücken zu geben (oder sie nicht zu zählen).
Bitte stimmen Sie hier ab "Einstellung hinzufügen, damit LEN nachgestellte Leerzeichen zählt":
https://feedback.azure.com/forums/908035-sql-server/suggestions/34673914-add-setting-so-len-counts-trailing-whitespace
Link "Connect im Ruhestand": https://connect.microsoft.com/SQLServer/feedback/details/801381
quelle
datalength
Lösung ist ab SQL Server 2012 noch schlechter, da sie jetzt Ersatzpaare in UTF-16 unterstützt, was bedeutet, dass ein Zeichen bis zu 4 Byte verwenden kann. Es ist wirklich an der Zeit, dielen
Funktion zur Einhaltung von ANSI festzulegen oder zumindest eine spezielle Funktion zum Zählen von Zeichen einschließlich nachfolgender Leerzeichen bereitzustellen.Es gibt Probleme mit den beiden am besten bewerteten Antworten. Die empfohlene Antwort
DATALENGTH
ist anfällig für Programmiererfehler. Das Ergebnis vonDATALENGTH
muss fürNVARCHAR
Typen durch 2 geteilt werden, nicht jedoch fürVARCHAR
Typen. Dies erfordert Kenntnisse über den Typ, dessen Länge Sie erhalten. Wenn sich dieser Typ ändert, müssen Sie die von Ihnen verwendeten Stellen sorgfältig ändernDATALENGTH
.Es gibt auch ein Problem mit der am besten bewerteten Antwort (was ich zugeben muss, war meine bevorzugte Methode, bis dieses Problem mich gebissen hat). Wenn das Objekt, dessen Länge Sie erhalten, vom Typ
NVARCHAR(4000)
ist und tatsächlich eine Zeichenfolge mit 4000 Zeichen enthält, ignoriert SQL das angehängte Zeichen, anstatt das Ergebnis implizit umzuwandelnNVARCHAR(MAX)
. Das Endergebnis ist eine falsche Länge. Das gleiche passiert mit VARCHAR (8000).Was ich gefunden habe, funktioniert, ist fast so schnell wie normal
LEN
, ist schneller alsLEN(@s + 'x') - 1
bei großen Zeichenfolgen und geht nicht davon aus, dass die zugrunde liegende Zeichenbreite wie folgt ist:Dies erhält die Datenlänge und dividiert dann durch die Datenlänge eines einzelnen Zeichens aus der Zeichenfolge. Der Anhang von 'x' deckt den Fall ab, in dem die Zeichenfolge leer ist (was in diesem Fall eine Division durch Null ergeben würde). Dies funktioniert , ob
@s
istVARCHAR
oderNVARCHAR
. Doing dieLEFT
von 1 Zeichen vor dem Anfügen Rasur einige Zeit , wenn die Zeichenfolge groß ist . Das Problem dabei ist jedoch, dass es mit Zeichenfolgen, die Ersatzpaare enthalten, nicht richtig funktioniert.Es gibt eine andere Möglichkeit, die in einem Kommentar zur akzeptierten Antwort mit erwähnt wird
REPLACE(@s,' ','x')
. Diese Technik gibt die richtige Antwort, ist jedoch einige Größenordnungen langsamer als die anderen Techniken, wenn die Zeichenfolge groß ist.Angesichts der Probleme, die Ersatzpaare bei jeder verwendeten Technik verursachen,
DATALENGTH
denke ich, dass die sicherste Methode, die mir die richtigen Antworten gibt, die folgenden ist:Dies ist schneller als die
REPLACE
Technik und viel schneller bei längeren Saiten. Grundsätzlich ist diese Technik dieLEN(@s + 'x') - 1
Technik, aber mit Schutz für den Randfall, in dem die Zeichenfolge eine Länge von 4000 (für nvarchar) oder 8000 (für varchar) hat, so dass auch dafür die richtige Antwort gegeben wird. Es sollte auch Zeichenfolgen mit Ersatzpaaren korrekt behandeln.quelle
N'x𤭢x' COLLATE Latin1_General_100_CI_AS_SC
4, während SieLEN
3 erhalten.Sie müssen auch sicherstellen, dass Ihre Daten tatsächlich mit den nachfolgenden Leerzeichen gespeichert werden. Wenn ANSI PADDING ausgeschaltet ist (nicht standardmäßig):
quelle
LEN schneidet standardmäßig nachgestellte Leerzeichen ab, daher habe ich festgestellt, dass dies funktioniert, wenn Sie sie nach vorne verschieben
(LEN (REVERSE (TestField))
Wenn Sie also wollten, könnten Sie sagen
Verwenden Sie dies natürlich nicht für führende Räume.
quelle
declare @TestField varchar(10);
SET @TestField = ' abc '; -- Length with spaces is 5.
select LEN(REVERSE(@TestField)) -- Returns 4
select LEN(@TestField) -- Returns 4
Sie sollten eine CLR-Funktion definieren, die das Feld Länge des Strings zurückgibt, wenn Sie die Konkatination von Strings nicht mögen. Ich verwende
LEN('x' + @string + 'x') - 2
in meiner Produktion Anwendungsfälle.quelle
Wenn Sie das
DATALENGTH
wegen n / varchar Bedenken nicht mögen, wie wäre es mit:das ist nur
umwickelt mit einem durch Null teilenden Schutz.
Durch Teilen durch die DATALENGTH eines einzelnen Zeichens erhalten wir die normalisierte Länge.
(Natürlich gibt es immer noch Probleme mit Ersatzpaaren, wenn das ein Problem ist.)
quelle
benutze SELECT DATALENGTH ('string')
quelle