J'ai la table de test suivante dans SQL Server 2005:
CREATE TABLE [dbo].[TestTable]
(
[ID] [int] NOT NULL,
[TestField] [varchar](100) NOT NULL
)
Rempli de:
INSERT INTO TestTable (ID, TestField) VALUES (1, 'A value'); -- Len = 7
INSERT INTO TestTable (ID, TestField) VALUES (2, 'Another value '); -- Len = 13 + 6 spaces
Lorsque j'essaie de trouver la longueur de TestField avec la fonction SQL Server LEN (), il ne compte pas les espaces de fin - par exemple:
-- 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
Comment inclure les espaces de fin dans le résultat de longueur?
sql-server
Jason Snelders
la source
la source
Réponses:
Ceci est clairement documenté par Microsoft dans MSDN à l' adresse http://msdn.microsoft.com/en-us/library/ms190329(SQL.90).aspx , qui indique LEN "renvoie le nombre de caractères de l'expression de chaîne spécifiée, à l'exclusion blancs de fin ". C'est, cependant, un détail facile à manquer si vous ne vous méfiez pas.
Vous devez à la place utiliser la fonction DATALENGTH - voir http://msdn.microsoft.com/en-us/library/ms173486(SQL.90).aspx - qui "renvoie le nombre d'octets utilisés pour représenter une expression".
Exemple:
la source
DATALENGTH
vous devrez également diviser le résultat par 2 si l'expression testée est un type de caractère large (Unicode; nchar, nvarchar ou ntext), car le résultat est en octets et non en caractères .varchar
etc. cela peut être collation à charge et même pas une division avant droite par 2 est fiable. Voir l' exemple iciLEN(REPLACE(expr, ' ', '_'))
. Cela devrait fonctionner avec les chaînesvarchar
etnvarchar
et contenant des caractères de contrôle Unicode spéciaux.DATALENGTH()
ne doit pas être considéré comme un moyen alternatif de compter les caractères car il compte des octets au lieu de caractères et cela est important lors de la représentation de la même chaîne dansVARCHAR
/NVARCHAR
.Vous pouvez utiliser cette astuce:
LEN (Str + 'x') - 1
la source
J'utilise cette méthode:
Je préfère cela à DATALENGTH car cela fonctionne avec différents types de données, et je préfère cela à l'ajout d'un caractère à la fin car vous n'avez pas à vous soucier du cas de bord où votre chaîne est déjà à la longueur maximale.
Remarque: je testerais les performances avant de l'utiliser sur un très grand ensemble de données; bien que je viens de le tester contre 2M de lignes et ce n'était pas plus lent que LEN sans le REMPLACER ...
la source
Vous demandez à quelqu'un de déposer une demande d'amélioration / rapport de bogue de SQL Server car presque toutes les solutions de contournement répertoriées à ce problème étonnamment simple ici présentent des lacunes ou sont inefficaces. Cela semble toujours être vrai dans SQL Server 2012. La fonction de découpage automatique peut provenir de ANSI / ISO SQL-92 mais il semble y avoir quelques trous (ou manque de les compter).
Veuillez voter pour "Ajouter un paramètre pour que LEN compte les espaces de fin" ici:
https://feedback.azure.com/forums/908035-sql-server/suggestions/34673914-add-setting-so-len-counts-trailing-whitespace
Lien de connexion retiré: https://connect.microsoft.com/SQLServer/feedback/details/801381
la source
datalength
solution est encore pire à partir de SQL Server 2012, car il prend désormais en charge les paires de substitution en UTF-16, ce qui signifie qu'un caractère peut utiliser jusqu'à 4 octets. Il est vraiment temps qu'ils corrigent lalen
fonction pour se conformer à ANSI, ou au moins fournissent une fonction dédiée pour compter les caractères, y compris les espaces de fin.Il y a des problèmes avec les deux réponses les plus votées. La réponse recommandée
DATALENGTH
est sujette à des erreurs de programmeur. Le résultat deDATALENGTH
doit être divisé par 2 pour lesNVARCHAR
types, mais pas pour lesVARCHAR
types. Cela nécessite la connaissance du type dont vous obtenez la longueur, et si ce type change, vous devez changer avec diligence les endroits que vous avez utilisésDATALENGTH
.Il y a aussi un problème avec la réponse la plus votée (ce que je reconnais était ma façon préférée de le faire jusqu'à ce que ce problème me mette en cause). Si l'élément dont vous obtenez la longueur est de type
NVARCHAR(4000)
et qu'il contient en fait une chaîne de 4 000 caractères, SQL ignorera le caractère ajouté au lieu de convertir implicitement le résultat enNVARCHAR(MAX)
. Le résultat final est une longueur incorrecte. La même chose se produira avec VARCHAR (8000).Ce que j'ai trouvé fonctionne, est presque aussi rapide que l'ancien
LEN
, est plus rapide queLEN(@s + 'x') - 1
pour les grandes chaînes et ne suppose pas que la largeur des caractères sous-jacents est la suivante:Cela obtient la longueur de données, puis divise par la longueur de données d'un seul caractère de la chaîne. L'ajout de «x» couvre le cas où la chaîne est vide (ce qui donnerait une division par zéro dans ce cas). Cela fonctionne que ce
@s
soitVARCHAR
ouNVARCHAR
. Faire le caractèreLEFT
de 1 avant l'ajout réduit le temps lorsque la chaîne est volumineuse. Le problème avec ceci cependant, c'est que cela ne fonctionne pas correctement avec des chaînes contenant des paires de substitution.Il y a une autre façon mentionnée dans un commentaire à la réponse acceptée, en utilisant
REPLACE(@s,' ','x')
. Cette technique donne la bonne réponse, mais est de quelques ordres de grandeur plus lente que les autres techniques lorsque la chaîne est grande.Compte tenu des problèmes introduits par les paires de substitution sur toute technique qui utilise
DATALENGTH
, je pense que la méthode la plus sûre qui donne des réponses correctes que je connaisse est la suivante:C'est plus rapide que la
REPLACE
technique, et beaucoup plus rapide avec des cordes plus longues. Fondamentalement, cette technique est laLEN(@s + 'x') - 1
technique, mais avec une protection pour le cas de bord où la chaîne a une longueur de 4000 (pour nvarchar) ou 8000 (pour varchar), de sorte que la bonne réponse est donnée même pour cela. Il doit également gérer correctement les chaînes avec des paires de substitution.la source
N'x𤭢x' COLLATE Latin1_General_100_CI_AS_SC
donne 4, tandis queLEN
donne 3.Vous devez également vous assurer que vos données sont effectivement enregistrées avec les blancs de fin. Lorsque ANSI PADDING est désactivé (non par défaut):
la source
LEN coupe les espaces de fin par défaut, donc j'ai trouvé que cela fonctionnait lorsque vous les déplacez vers l'avant
(LEN (REVERSE (TestField))
Donc si tu le voulais, tu pourrais dire
N'utilisez pas cela pour diriger des espaces bien sûr.
la source
declare @TestField varchar(10);
SET @TestField = ' abc '; -- Length with spaces is 5.
select LEN(REVERSE(@TestField)) -- Returns 4
select LEN(@TestField) -- Returns 4
Vous devez définir une fonction CLR qui renvoie le champ Longueur de la chaîne, si vous n'aimez pas la concatination de chaînes. j'utilise
LEN('x' + @string + 'x') - 2
dans mes cas d'utilisation de production.la source
Si vous n'aimez pas le en
DATALENGTH
raison de préoccupations n / varchar, que diriez-vous:qui est juste
enveloppé d'une protection de division par zéro.
En divisant par la DATALENGTH d'un seul caractère, nous obtenons la longueur normalisée.
(Bien sûr, il y a toujours des problèmes avec les paires de substitution si cela pose un problème.)
la source
utilisez SELECT DATALENGTH ('string')
la source