Reemplazar espacios duplicados con un solo espacio en T-SQL

Necesito asegurarme de que un campo determinado no tenga más de un espacio (no me preocupan todos los espacios en blanco, solo el espacio) entre los caracteres.

Asi que

'single spaces only' 

necesita ser convertido en

 'single spaces only' 

Lo siguiente no funcionará

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

ya que resultaría en

 'single spaces only' 

Realmente preferiría seguir con T-SQL nativo en lugar de una solución basada en CLR.

¿Pensamientos?

Incluso más ordenado:

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

Salida:

seleccionar espacios individuales

Esto funcionaría:

 declare @test varchar(100) set @test = 'this is a test' while charindex(' ',@test ) > 0 begin set @test = replace(@test, ' ', ' ') end select @test 

Si sabe que no habrá más de un cierto número de espacios en una fila, puede anidar el reemplazo:

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

4 reemplaces deberían arreglar hasta 16 espacios consecutivos (16, luego 8, luego 4, luego 2, luego 1)

Si podría ser significativamente más largo, entonces tendría que hacer algo como una función en línea:

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

Entonces solo hazlo

 SELECT dbo.strip_spaces(myText) FROM myTable 

Esto es algo de fuerza bruta, pero funcionará

 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 
 update mytable set myfield = replace (myfield, ' ', ' ') where charindex(' ', myfield) > 0 

Reemplazar funcionará en todos los espacios dobles, sin necesidad de agregar múltiples reemplazos. Esta es la solución basada en conjuntos.

Se puede hacer recursivamente a través de la función:

 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 

entonces, por ejemplo:

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

devoluciones:

 NewStr some string with many spaces 

O la solución basada en el método descrito por @ agdk26 o @Neil Knight (pero más seguro)
ambos ejemplos devuelven el resultado anterior:

 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... 

o

 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 

Cómo funciona: enter image description here

Precaución:
El cordel / cuerda usado para reemplazar los espacios no debería existir al principio o al final de la cuerda y solo.

Aquí hay una función simple que creé para limpiar cualquier espacio antes o después, y múltiples espacios dentro de una cadena. Maneja con gracia hasta 108 espacios en un solo tramo y tantos bloques como hay en la cadena. Puede boost eso por factores de 8 agregando líneas adicionales con espacios más grandes si es necesario. Parece funcionar rápidamente y no ha causado ningún problema a pesar de su uso generalizado en una aplicación grande.

 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 

Encontrado esto mientras buscabas una respuesta:

 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 respuesta completa (con explicación) fue extraída de: http://techtipsbysatish.blogspot.com/2010/08/sql-server-replace-multiple-spaces-with.html

En segundo lugar, parece ser una versión ligeramente diferente de la respuesta seleccionada.

Esta es la solución a través de reemplazo múltiple, que funciona para cualquier cadena (no necesita caracteres especiales, que no son parte de la cadena).

 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' 

Método 1

El primer método es reemplazar espacios extra entre palabras con una combinación de símbolo poco común como marcador temporal. Luego puede reemplazar los símbolos de marcadores temporales usando la función de reemplazo en lugar de un bucle.

Aquí hay un ejemplo de código que reemplaza el texto dentro de una variable String.

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

Prueba de tiempo de ejecución # 1: en diez ejecuciones de este método de reemplazo, el tiempo promedio de espera en las respuestas del servidor fue de 1.7 milisegundos y el tiempo de ejecución total fue de 4.6 milisegundos. Prueba de tiempo de ejecución # 2: el tiempo promedio de espera en las respuestas del servidor fue de 1.7 milisegundos y el tiempo total de ejecución fue de 3.7 milisegundos.

Método n. ° 2

El segundo método no es tan elegante como el primero, pero también hace el trabajo. Este método funciona anidando cuatro (u opcionalmente más) declaraciones de reemplazo que reemplazan dos espacios en blanco con un espacio en blanco.

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

Prueba de tiempo de ejecución # 1: en diez ejecuciones de este método de reemplazo, el tiempo promedio de espera en las respuestas del servidor fue de 1.9 milisegundos y el tiempo total de ejecución fue de 3.8 milisegundos. Prueba de tiempo de ejecución # 2: el tiempo promedio de espera en las respuestas del servidor fue de 1.8 milisegundos y el tiempo total de ejecución fue de 4.8 milisegundos.

Método n. ° 3

El tercer método para reemplazar espacios extra entre palabras es usar un bucle simple. Puede verificar espacios adicionales en un ciclo while y luego usar la función reemplazar para reducir los espacios extra con cada iteración del ciclo.

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

Prueba de tiempo de ejecución # 1: en diez ejecuciones de este método de reemplazo, el tiempo promedio de espera en las respuestas del servidor fue de 1.8 milisegundos y el tiempo total de ejecución fue de 3.4 milisegundos. Prueba de tiempo de ejecución # 2: el tiempo promedio de espera en las respuestas del servidor fue de 1.9 milisegundos y el tiempo total de ejecución fue de 2.8 milisegundos.

 update mytable set myfield = replace(myfield, ' ', ' ') where myfield like '% %' 

Prueba esto..

Puedes intentar esto:

 select Regexp_Replace('single spaces only','( ){2,}', ' ') from dual;