2010-02-02 12 views

risposta

26

Ecco un semplice metodo basato sulla modalità che collassa più spazi in un unico spazio applicando tre sostituzioni.

DECLARE @myTable TABLE (myTextColumn VARCHAR(50)) 

INSERT INTO @myTable VALUES ('0Space') 
INSERT INTO @myTable VALUES (' 1 Spaces 1 Spaces. ') 
INSERT INTO @myTable VALUES (' 2 Spaces 2 Spaces. ') 
INSERT INTO @myTable VALUES (' 3 Spaces 3 Spaces. ') 
INSERT INTO @myTable VALUES (' 4 Spaces 4 Spaces. ') 
INSERT INTO @myTable VALUES ('  5  Spaces 5  Spaces.  ') 
INSERT INTO @myTable VALUES ('  6  Spaces 6  Spaces.  ') 

select replace(
      replace(
      replace(
       LTrim(RTrim(myTextColumn)), ---Trim the field 
      ' ',' |'),     ---Mark double spaces 
      '| ',''),       ---Delete double spaces offset by 1 
     '|','')        ---Tidy up 
     AS SingleSpaceTextColumn 
from @myTable 

l'istruzione UPDATE può ora essere impostato in base:

update @myTable 
    set myTextColumn = replace(
          replace(
          replace(
           LTrim(RTrim(myTextColumn)), 
          ' ',' |'), 
          '| ',''), 
         '|','') 

Utilizzare un adeguato clausola WHERE per limitare l'aggiornamento per solo le righe che avere bisogno di aggiornare o forse hanno doppi spazi.

Esempio:

where 1<=Patindex('% %', myTextColumn) 

ho trovato una scrittura esterno fino su questo metodo: REPLACE Multiple Spaces with One

+0

Penso che questo sia lo stesso della risposta di Paolo, ma i tuoi commenti lo rendono un po 'più leggibile – cindi

+1

Ben individuati sono lo stesso metodo. – Andrew

+0

Riferimenti esterni chiarito cose – cindi

2

Passo attraverso i caratteri uno a uno, e mantenere un record di il personaggio precedente. Se il carattere corrente è uno spazio e l'ultimo carattere è uno spazio, lo è stuff.

CREATE FUNCTION [dbo].[fnRemoveExtraSpaces] (@Number AS varchar(1000)) 
Returns Varchar(1000) 
As 
Begin 
Declare @n int -- Length of counter 
Declare @old char(1) 

Set @n = 1 
--Begin Loop of field value 
While @n <=Len (@Number) 
    BEGIN 
    If Substring(@Number, @n, 1) = ' ' AND @old = ' ' 
     BEGIN 
     Select @Number = Stuff(@Number , @n , 1 , '') 
     END 
    Else 
     BEGIN 
     SET @old = Substring(@Number, @n, 1) 
     Set @n = @n + 1 
     END 
    END 
Return @number 
END 
GO 


select [dbo].[fnRemoveExtraSpaces]('xxx  xxx  xxx xxx') 
0
create table blank(
field_blank char(100)) 

insert into blank values('yyy  yyyy') 
insert into blank values('xxxx xxxx') 
insert into blank values ('xxx xxx') 
insert into blank values ('zzzzzz zzzzz') 

update blank 
set field_blank = substring(field_blank,1,charindex(' ',field_blank)-1) + ' ' + ltrim(substring(field_blank,charindex(' ',field_blank) + 1,len(field_blank))) 
where CHARINDEX (' ' , rtrim(field_blank)) > 1 

select * from blank 
+2

non funziona su più occorrenze di spazi eccessivi. – cjk

+0

@ck: Sono interessato a vedere il ciclo in sql. Puoi postare come aggiornamento per la tua risposta. tia. – Saar

3

Non molto impostato in base, ma un semplice WHILE farebbe il trucco.

CREATE TABLE #myTable (myTextColumn VARCHAR(32)) 

INSERT INTO #myTable VALUES ('NoSpace') 
INSERT INTO #myTable VALUES ('One Space') 
INSERT INTO #myTable VALUES ('Two Spaces') 
INSERT INTO #myTable VALUES ('Multiple Spaces .') 

WHILE EXISTS (SELECT * FROM #myTable WHERE myTextColumn LIKE '% %') 
    UPDATE #myTable 
    SET  myTextColumn = REPLACE(myTextColumn, ' ', ' ') 
    WHERE myTextColumn LIKE '% %' 

SELECT * FROM #myTable 

DROP TABLE #myTable 
+0

Naturalmente, questo non funzionerà su SQL Server 2000 a causa della clausola 'OUTPUT', ma una buona risposta. – Codesleuth

+0

@Codesleuth - grazie, mi mancava quel requisito. La risposta è stata aggiornata per funzionare con SQL Server 2000. –

+0

aww, ma è stato modificato in una tabella temporanea? Questo mi rende triste, le tabelle dichiarate funzionano anche nel 2000, sai! – Codesleuth

28

Questo funziona:

UPDATE myTable 
SET myTextColumn = 
    REPLACE(
     REPLACE(
      REPLACE(myTextColumn 
       ,' ',' '+CHAR(1)) -- CHAR(1) is unlikely to appear 
     ,CHAR(1)+' ','') 
    ,CHAR(1),'') 
WHERE myTextColumn LIKE '% %' 

interamente a base di set; nessun loop.

Quindi sostituiamo due spazi con un carattere insolito e uno spazio. Se chiamiamo il carattere insolito X, diventano 5 spazi: "X X" e 6 spazi diventano "X X X". Quindi sostituiamo 'X' con la stringa vuota. Quindi 5 spazi diventano '' e 6 spazi diventano 'X'. Quindi, nel caso ci fosse un numero pari di spazi, rimuoviamo le "X" rimanenti, lasciando un singolo spazio.

+0

Tecnicamente 'SOSTITUISCI' scorre il testo ... – cjk

+0

Tecnicamente, vero. Ma tecnicamente praticamente qualsiasi SQL comporterà un ciclo. Avrei dovuto dire che utilizza una singola query. – Paul

+0

Evita astutamente il loop attorno al tavolo. Mi chiedo se potrebbe essere reso più leggibile anche se – cindi

3
SELECT 'starting...' --sets @@rowcount 
WHILE @@rowcount <> 0 
    update myTable 
    set myTextColumn = replace(myTextColumn, ' ', ' ') 
    where myTextColumn like '% %' 
+1

Cheeky, ma non particolarmente efficiente ... – cjk

+0

Preferisco "Elegante e semplice" ... – gbn

+0

Utilizzare il conteggio delle righe con la clausola where era una buona idea – cindi

-2
Update myTable set myTextColumn = replace(myTextColumn, ' ', ' '); 

La query sopra rimuoverà tutti gli spazi vuoti con doppio singolo spazio vuoto

Ma questo avrebbe funzionato solo una volta.

+0

da cui il mio ciclo .... – cindi

+0

@cjk è chiaramente menzionato nella risposta, funzionerebbe solo una volta. – Ravia

+0

Ed è chiaramente menzionato nella domanda che l'OP vuole sostituire RIPETERE gli spazi con un singolo spazio. L'esempio nella domanda ha anche l'SQL in esso che hai postato come risposta, e lei ha un ciclo (WHILE) per eseguire ripetutamente la sostituzione double-to-single. A proposito, NON ho votato giù. –

0

Per me gli esempi sopra riportati quasi fatto un trucco, ma avevo bisogno di qualcosa che era più stabile e indipendente dal tabella o colonna o un numero stabilito di iterazioni. Quindi questa è la mia modifica dalla maggior parte delle query di cui sopra.

CREATE FUNCTION udfReplaceAll 
(
    @OriginalText NVARCHAR(MAX), 
    @OldText NVARCHAR(MAX), 
    @NewText NVARCHAR(MAX) 
) 
RETURNS NVARCHAR(MAX) 
AS 
BEGIN 
    WHILE (@OriginalText LIKE '%' + @OldText + '%') 
    BEGIN 
     SET @OriginalText = REPLACE(@OriginalText,@OldText,@NewText) 
    END 

    RETURN @OriginalText 
END 
GO 
0

consente di dire, i tuoi dati come questo

Table name : userdata Field: id, comment, status, 

id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br> 
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br> 
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br> 
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br> 

Quindi, basta fare come questo

update userdata set comment=REPLACE(REPLACE(comment," ","-SPACEHERE-"),"-SPACEHERE"," "); 

Non ho provato, ma penso questo funzionerà.

0

Ecco una soluzione più semplice :)

update myTable 
    set myTextColumn = replace(replace(replace(LTrim(RTrim(myTextColumn)),' ','<>'),'><',''),'<>',' ') 
0

Prova questa:

UPDATE Ships 
SET name = REPLACE(REPLACE(REPLACE(name, ' ', ' ' + CHAR(1)), CHAR(1) + ' ', ''), CHAR(1), '') 
WHERE name LIKE '% %' 
Problemi correlati