web-dev-qa-db-fra.com

Remplacer les espaces en double par un seul espace dans T-SQL

Je dois m'assurer qu'un champ donné n'a pas plus d'un espace (je ne suis pas concerné par tous les espaces blancs, mais uniquement par l'espace) entre les caractères.

Alors

'single    spaces   only'

doit être transformé en 

'single spaces only'

Le ci-dessous ne fonctionnera pas

select replace('single    spaces   only','  ',' ')

comme il en résulterait 

'single  spaces  only'

Je préférerais vraiment rester avec T-SQL natif plutôt qu’une solution basée sur le CLR.

Pensées?

84
Christoph

Encore plus ordonné:

select string = replace(replace(replace(' select   single       spaces',' ','<>'),'><',''),'<>',' ')

Sortie:

sélectionner des espaces simples

266
Neil Knight

Cela fonctionnerait:

declare @test varchar(100)
set @test = 'this   is  a    test'

while charindex('  ',@test  ) > 0
begin
   set @test = replace(@test, '  ', ' ')
end

select @test
20
James Wiseman

Si vous savez qu'il n'y aura pas plus d'un certain nombre d'espaces à la suite, vous pouvez simplement imbriquer le remplacement:

replace(replace(replace(replace(myText,'  ',' '),'  ',' '),'  ',' '),'  ',' ')

4 remplacements doivent corriger jusqu'à 16 espaces consécutifs (16, puis 8, puis 4, puis 2 et 1)

Si cela pouvait être beaucoup plus long, alors vous devriez faire quelque chose comme une fonction en ligne:

CREATE FUNCTION strip_spaces(@str varchar(8000))
RETURNS varchar(8000) AS
BEGIN 
    WHILE CHARINDEX('  ', @str) > 0 
        SET @str = REPLACE(@str, '  ', ' ')

    RETURN @str
END

Alors fais juste

SELECT dbo.strip_spaces(myText) FROM myTable
12
BradC

C'est un peu la force brutale, mais cela fonctionnera

CREATE FUNCTION stripDoubleSpaces(@prmSource varchar(max)) Returns varchar(max)
AS 
BEGIN
    WHILE (PATINDEX('%  %', @prmSource)>0)
     BEGIN
        SET @prmSource = replace(@prmSource  ,'  ',' ')
     END

    RETURN @prmSource
END

GO

-- Unit test -- 
PRINT dbo.stripDoubleSpaces('single    spaces   only')

single spaces only
5
JohnFx
update mytable
set myfield = replace (myfield, '  ',  ' ')
where charindex('  ', myfield) > 0 

Remplacer fonctionnera sur tous les doubles espaces, pas besoin de mettre plusieurs remplacements. Ceci est la solution basée sur les ensembles. 

5
HLGEM

Cela peut être fait de manière récursive via la fonction:

CREATE FUNCTION dbo.RemSpaceFromStr(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX) AS
BEGIN
  RETURN (CASE WHEN CHARINDEX('  ', @str) > 0 THEN
    dbo.RemSpaceFromStr(REPLACE(@str, '  ', ' ')) ELSE @str END);
END

alors, par exemple:

SELECT dbo.RemSpaceFromStr('some   string    with         many     spaces') AS NewStr

résultats:

NewStr
some string with many spaces

Ou la solution basée sur la méthode décrite par @ agdk26 ou @Neil Knight (mais plus sûre)
les deux exemples renvoient la sortie ci-dessus:

SELECT REPLACE(REPLACE(REPLACE('some   string    with         many     spaces'
  , '  ', ' ' + CHAR(7)), CHAR(7) + ' ', ''), ' ' + CHAR(7), ' ') AS NewStr 
--but it remove CHAR(7) (Bell) from string if exists...

ou 

SELECT REPLACE(REPLACE(REPLACE('some   string    with         many     spaces'
  , '  ', ' ' + CHAR(7) + CHAR(7)), CHAR(7) + CHAR(7) + ' ', ''), ' ' + CHAR(7) + CHAR(7), ' ') AS NewStr
--but it remove CHAR(7) + CHAR(7) from string

Comment ça marche:  enter image description here

Mise en garde:
Les caractères/chaînes utilisés pour remplacer les espaces ne doivent pas exister au début ou à la fin de la chaîne et sont autonomes.

4
Adam Silenko

Voici une fonction simple que j'ai créée pour nettoyer tous les espaces avant ou après, ainsi que plusieurs espaces dans une chaîne. Il gère gracieusement jusqu'à environ 108 espaces en un seul passage et autant de blocs que dans la chaîne. Vous pouvez augmenter ce facteur de 8 en ajoutant des lignes supplémentaires avec de plus grands espaces si nécessaire. Il semble fonctionner rapidement et n'a posé aucun problème malgré son utilisation généralisée dans une application volumineuse.

CREATE FUNCTION [dbo].[fnReplaceMultipleSpaces] (@StrVal AS VARCHAR(4000)) 
RETURNS VARCHAR(4000) 
AS 
BEGIN

    SET @StrVal = Ltrim(@StrVal)
    SET @StrVal = Rtrim(@StrVal)

    SET @StrVal = REPLACE(@StrVal, '                ', ' ')  -- 16 spaces
    SET @StrVal = REPLACE(@StrVal, '        ', ' ')  -- 8 spaces
    SET @StrVal = REPLACE(@StrVal, '    ', ' ')  -- 4 spaces
    SET @StrVal = REPLACE(@StrVal, '  ', ' ')  -- 2 spaces
    SET @StrVal = REPLACE(@StrVal, '  ', ' ')  -- 2 spaces (for odd leftovers)

RETURN @StrVal

END
2
Robert Petolillo

C'est la solution via le remplacement multiple, qui fonctionne pour toutes les chaînes (ne nécessite pas de caractères spéciaux, qui ne font pas partie de la chaîne).

declare @value varchar(max)
declare @result varchar(max)
set @value = 'alpha   beta gamma  delta       xyz'

set @result = replace(replace(replace(replace(replace(replace(replace(
  @value,'a','ac'),'x','ab'),'  ',' x'),'x ',''),'x',''),'ab','x'),'ac','a')

select @result -- 'alpha beta gamma delta xyz'
1
agdk26

J'ai trouvé ceci en cherchant une réponse:

SELECT REPLACE(
        REPLACE(
             REPLACE(
                LTRIM(RTRIM('1 2  3   4    5     6'))
            ,'  ',' '+CHAR(7))
        ,CHAR(7)+' ','')
    ,CHAR(7),'') AS CleanString
where charindex('  ', '1 2  3   4    5     6') > 0

La réponse complète (avec explication) a été tirée de: http://techtipsbysatish.blogspot.com/2010/08/sql-server-replace-multiple-spaces-with.html

Au second regard, semble être juste une version légèrement différente de la réponse sélectionnée.

1
Limey

J'utilise généralement cette approche:

declare @s varchar(50)
set @s = 'TEST         TEST'
select REPLACE(REPLACE(REPLACE(@s,' ','[o][c]'),'[c][o]',''),'[o][c]',' ')
0
Matthys Du Toit
 DECLARE @str varchar(150)
SET @str='Hello    My   name  is Jiyaul   mustafa'
Select REPLACE(REPLACE(REPLACE(@str,' ','{}'),'}{',''),'{}',' ')
0
JIYAUL MUSTAPHA

Méthode n ° 1

La première méthode consiste à remplacer les espaces supplémentaires entre les mots par une combinaison de symboles inhabituelle en tant que marqueur temporaire. Vous pouvez ensuite remplacer les symboles de marqueur temporaires à l'aide de la fonction de remplacement plutôt que d'une boucle.

Voici un exemple de code qui remplace le texte dans une variable String.

DECLARE @testString AS VARCHAR(256) = ' Test        text   with  random*        spacing. Please normalize  this spacing!';
SELECT REPLACE(REPLACE(REPLACE(@testString, ' ', '*^'), '^*', ''), '*^', ' ');

Test du temps d'exécution n ° 1: lors de dix exécutions de cette méthode de remplacement, le temps d'attente moyen des réponses du serveur était de 1,7 millisecondes et le temps d'exécution total de 4,6 millisecondes. millisecondes et le temps d'exécution total était de 3,7 millisecondes.

Méthode n ° 2

La deuxième méthode n’est pas aussi élégante que la première, mais elle permet également de faire le travail. Cette méthode consiste à imbriquer quatre (ou éventuellement plusieurs) instructions de remplacement qui remplacent deux espaces vides par un seul.

DECLARE @testString AS VARCHAR(256) = ' Test        text   with  random*        spacing. Please normalize  this spacing!';
SELECT REPLACE(REPLACE(REPLACE(REPLACE(@testString,' ',' '),' ',' '),' ',' '),' ',' ')

Test du temps d'exécution n ° 1: lors de dix exécutions de cette méthode de remplacement, le temps d'attente moyen des réponses du serveur était de 1,9 millisecondes et le temps d'exécution total de 3,8 millisecondes . Test du temps d'exécution n ° 2: le temps d'attente moyen des réponses du serveur était de 1,8 millisecondes et le temps d'exécution total était de 4,8 millisecondes.

Méthode n ° 3

La troisième méthode pour remplacer les espaces supplémentaires entre les mots consiste à utiliser une simple boucle. Vous pouvez vérifier les espaces supplémentaires dans une boucle while, puis utiliser la fonction replace pour réduire les espaces supplémentaires à chaque itération de la boucle.

DECLARE @testString AS VARCHAR(256) = ' Test text with random* spacing. Please normalize this spacing!';
WHILE CHARINDEX(' ',@testString) > 0
SET @testString = REPLACE(@testString, ' ', ' ')
SELECT @testString

Test du temps d'exécution n ° 1: lors de dix exécutions de cette méthode de remplacement, le temps d'attente moyen des réponses du serveur était de 1,8 millisecondes et le temps d'exécution total de 3,4 millisecondes . Test du temps d'exécution n ° 2: le temps d'attente moyen des réponses du serveur était de 1,9 millisecondes et le temps d'exécution total était de 2,8 millisecondes.

0
user6097216

J'utilise la solution FOR XML PATH pour remplacer plusieurs espaces en un seul espace

L'idée est de remplacer les espaces par des balises XML, puis de scinder une chaîne XML en fragments de chaîne sans balises XML. Enfin, concaténez ces valeurs de chaîne en ajoutant des caractères d'espacement uniques entre deux

Voici comment la fonction UDF finale peut être appelée

select dbo.ReplaceMultipleSpaces('   Sample   text  with  multiple  space     ')
0
Eralper