Quelle est une bonne façon de couper tous les caractères blancs d'espace d'une chaîne en T-SQL sans UDF et sans CLR?
.NET fonction string.Trim
mic un assez vaste ensemble d'espaces . Comment ce comportement exact pourrait-il être émulé de la meilleure façon T-SQL?
LTRIM
et RTRIM
seulement couper le caractère d'espace qui n'est pas assez.
ce serait facile avec SQL CLR, mais ce n'est pas toujours possible et a également un coût d'invocation assez élevé. Donc je voudrais éviter SQL CLR.
De plus, les UDFs scalaires forcent les plans en série et sont lents à invoquer. Donc ça ne devrait pas être un UDF scalaire, non plus.
compte tenu de ces contraintes, Quelle est la meilleure façon de procéder?
2 réponses
ce code fournit un motif que vous pouvez étendre pour gérer l'espace blanc de votre choix pour un modifié LTRIM
.
declare @Tab as NVarChar(1) = NChar( 9 );
declare @Space as NVarChar(1) = NChar( 32 );
declare @Samples as Table ( String NVarChar(16) );
insert into @Samples ( String ) values
( 'Foo' ),
( @Tab + 'Foo' ),
( @Space + 'Foo' ),
( @Space + @Tab + 'Foo' ),
( @Tab + @Space + 'Foo' );
select String, Len( String ) as [Length], PatIndex( '%[^' + @Tab + @Space + ']%', String ) - 1 as [WhitespaceCount]
from @Samples;
la fonction REVERSE
peut être utilisée pour implémenter une version modifiée de RTRIM
.
NEWER UPDATE :
Le code suivant utilise la liste des caractères blancs utilisés dans .net Framework 4. Il fonctionne également autour de la fonction de LEN
sans compter les blancs traînants.
declare @Tab as NVarChar(1) = NChar( 9 );
declare @Space as NVarChar(1) = NChar( 32 );
declare @Samples as Table ( String NVarChar(16) );
insert into @Samples ( String ) values
( 'Foo' ),
( @Tab + 'Foo' ),
( @Space + 'Foo' ),
( @Space + @Tab + 'Foo' ),
( @Tab + @Space + 'Foo' ),
( @Tab + 'Foo' + @Space ),
( @Space + 'Foo' + @Tab ),
( @Space + @Tab + 'Foo' + @Tab + @Space ),
( @Tab + @Space + 'Foo' + @Space + @Tab ),
( 'Foo' + @Tab ),
( NULL ),
( ' ' ),
( @Space + NULL + @Tab + @Tab ),
( '' ),
( 'Hello world!' );
declare @WhitespacePattern as NVarChar(100) = N'%[^' +
NChar( 0x0020 ) + NChar( 0x00A0 ) + NChar( 0x1680 ) + NChar( 0x2000 ) +
NChar( 0x2001 ) + NChar( 0x2002 ) + NChar( 0x2003 ) + NChar( 0x2004 ) +
NChar( 0x2005 ) + NChar( 0x2006 ) + NChar( 0x2007 ) + NChar( 0x2008 ) +
NChar( 0x2009 ) + NChar( 0x200A ) + NChar( 0x202F ) + NChar( 0x205F ) +
NChar( 0x3000 ) + NChar( 0x2028 ) + NChar( 0x2029 ) + NChar( 0x0009 ) +
NChar( 0x000A ) + NChar( 0x000B ) + NChar( 0x000C ) + NChar( 0x000D ) +
NChar( 0x0085 ) + N']%';
-- NB: The Len function does not count trailing spaces.
-- Use DataLength instead.
with AnalyzedSamples as (
select String, DataLength( String ) / DataLength( NChar( 42 ) ) as [StringLength],
PatIndex( @WhitespacePattern, String ) - 1 as [LeftWhitespace],
PatIndex( @WhitespacePattern, Reverse( String ) ) - 1 as [RightWhitespace]
from @Samples ),
TrimmedSamples as (
select String, StringLength, [LeftWhitespace], [RightWhitespace],
case
when String is NULL then NULL
when LeftWhitespace = -1 then N''
else Substring( String, LeftWhitespace + 1, StringLength - LeftWhitespace )
end as [LTrim],
case
when String is NULL then NULL
when RightWhitespace = -1 then N''
else Reverse( Substring( Reverse( String ), RightWhitespace + 1, StringLength - RightWhitespace ) )
end as [RTrim],
case
when String is NULL then NULL
when LeftWhitespace = -1 then N''
else Substring( String, LeftWhitespace + 1, StringLength - LeftWhitespace - RightWhitespace )
end as [Trim]
from AnalyzedSamples )
select N'"' + String + N'"' as [String], StringLength, [LeftWhitespace], [RightWhitespace],
N'"' + [LTrim] + N'"' as [LTrim], DataLength( [LTRIM] ) / DataLength( NChar( 42 ) ) as [LTrimLength],
N'"' + [RTrim] + N'"' as [RTrim], DataLength( [RTRIM] ) / DataLength( NChar( 42 ) ) as [RTrimLength],
N'"' + [Trim] + N'"' as [Trim], DataLength( [TRIM] ) / DataLength( NChar( 42 ) ) as [TrimLength]
from TrimmedSamples;
je serais intéressé de voir si quelqu'un trouve une solution SQL générique.
le mieux que je puisse trouver est une simple fonction de remplacement:
SELECT MyString = LEFT(MyString, LEN(RTRIM(REPLACE(REPLACE(REPLACE(MyString COLLATE Latin1_General_100_BIN2, NCHAR(9), ' '), NCHAR(12), ' '), NCHAR(13), ' ')))) AS RTrimmed
SELECT MyString = RIGHT(MyString, LEN(LTRIM(REPLACE(REPLACE(REPLACE(MyString COLLATE Latin1_General_100_BIN2, NCHAR(9), ' '), NCHAR(12), ' '), NCHAR(13), ' ')))) AS LTrimmed
etc.
vous pouvez obtenir la liste des caractères blancs actuels ici:
http://unicode.org/charts/uca/chart_Whitespace.html
ou, pour vous le prouver, vous pourriez exporter une liste de tous les caractères de SQL Server à quelque chose comme Excel, nettoyer les caractères, et les importer de nouveau. Ce qui a été enlevé était de l'espace blanc.