2010-03-16 26 views
66

Tôi cần đảm bảo rằng một trường nhất định không có nhiều khoảng trống (tôi không quan tâm đến tất cả khoảng trắng, chỉ khoảng trắng) giữa các ký tự.Thay thế không gian trùng lặp bằng một khoảng trống trong T-SQL

Vì vậy

'single spaces only' 

cần phải được biến thành

'single spaces only' 

dưới đây sẽ không làm việc

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

vì nó sẽ cho kết quả trong

'single spaces only' 

Tôi thực sự thích gắn bó với T-SQL gốc hơn là giải pháp dựa trên CLR.

Suy nghĩ?

+0

Bạn có thể làm điều này với một regex thay thế –

+1

trùng lặp có thể xảy ra [phương pháp SQL để thay thế chỗ trống lặp đi lặp lại với khoảng trống duy nhất] (http://stackoverflow.com/questions/2182877/sql-method-to-replace-repeating-khoảng trống-với-đơn-khoảng trống) – bummi

Trả lời

218

Thậm chí ngăn nắp:

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

Output:

chọn không gian đơn

+5

Nếu bạn muốn loại bỏ các khoảng trống ở phía trước và cuối của chuỗi, sau đó bọc thay thế trong một LTRIM, RTRIM và nó sẽ làm điều đó cho bạn. –

+3

Miễn là chuỗi của bạn không chứa nhiều dấu hiệu < or >. Dường như mong manh cho ý thích của tôi. – JohnFx

+7

Hack thực sự thanh lịch. Được thăng hạng. Bất kỳ hai ký tự nào cũng có thể được sử dụng cho phần giữa nếu <> có khả năng trong văn bản đầu vào. – richardtallent

18

này sẽ làm việc:

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

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

select @test 
+1

Gói chức năng và thay đổi varchar (100) thành nvarchar (tối đa) –

+0

phức tạp của nó trông phức tạp, thủ thuật của neil là tốt hơn. –

+0

Sự khác biệt giữa kịch bản của James và Neil là James chạy mặc dù trong vòng lặp đó, trong kinh nghiệm cá nhân, có nó chạy mặc dù 50.000 hồ sơ của một bảng có xu hướng rất chậm, vì vậy bạn cần phải tạo nó như là một thủ tục và vượt qua trong một kỷ lục và một số công việc bạn có thể không có quyền tạo quy trình mới cho ban nhạc. Neil sử dụng các hàm đã tồn tại vì nó sử dụng <>, nếu bạn có một chuỗi như '" release <><<><> now "', '" release <<> now " ',' "release

3

Đây là lực lượng có phần vũ phu, nhưng sẽ làm việc

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 
9

Nếu bạn biết sẽ không có nhiều hơn một số lượng nhất định của không gian trong một hàng, bạn có thể chỉ tổ thay thế:

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

4 Thay thế nên sửa chữa lên đến 16 liên tiếp không gian (16, sau đó 8, sau đó 4, sau đó 2, sau đó 1)

Nếu nó có thể là dài hơn đáng kể, sau đó bạn sẽ phải làm một cái gì đó giống như một in-line chức năng:

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

    RETURN @str 
END 

Sau đó chỉ cần làm

SELECT dbo.strip_spaces(myText) FROM myTable 
+0

Brad, tôi đã có mã số gần như giống hệt nhau nhưng bạn đã đánh bại tôi đến Bưu điện, vì vậy upvote. Nhiều cuộc gọi REPLACE() bị hack, nhưng nếu số lượng các khoảng trống "dự kiến" dự đoán và tương đối nhỏ, nó sẽ làm tốt và đáp ứng yêu cầu của OP không gọi mã RegEx thông qua CLR. – richardtallent

2
update mytable 
set myfield = replace (myfield, ' ', ' ') 
where charindex(' ', myfield) > 0 

Thay thế sẽ làm việc trên tất cả các không gian đôi, không cần phải đưa vào nhiều thay thế. Đây là giải pháp dựa trên tập hợp.

+0

Điều này có làm sụp đổ 4 không gian thành 2 không? –

+0

Tôi gọi giải pháp này trong các câu hỏi của tôi là không đáp ứng được nhu cầu, nhưng cảm ơn. –

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

Hãy thử điều này ..

+0

Tôi gọi giải pháp này trong câu hỏi của tôi là không đáp ứng nhu cầu, nhưng cảm ơn. –

1

Đây là giải pháp thông qua nhiều thay thế, mà làm việc cho bất kỳ chuỗi (không cần ký tự đặc biệt, không phải là một phần của chuỗi).

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' 
+0

điều tốt đẹp, nhưng thay đổi 'abe' thành 'axe' –

+0

lỗi cố định trong mã (khi thay đổi abe-> axe) – agdk26

1

Tìm thấy điều này trong khi đào một câu trả lời:

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 

Câu trả lời đầy đủ (với lời giải thích) được kéo từ: http://techtipsbysatish.blogspot.com/2010/08/sql-server-replace-multiple-spaces-with.html

Mở cái nhìn thứ hai, dường như chỉ là một phiên bản hơi khác nhau của câu trả lời đã chọn.

2

Đây là một hàm đơn giản mà tôi đã tạo để làm sạch bất kỳ dấu cách nào trước hoặc sau và nhiều dấu cách trong một chuỗi. Nó duyên dáng xử lý lên đến khoảng 108 không gian trong một đoạn duy nhất và như nhiều khối như có trong chuỗi. Bạn có thể tăng điều đó bằng các yếu tố của 8 bằng cách thêm các dòng bổ sung với các khoảng không gian lớn hơn nếu bạn cần. Dường như nó hoạt động nhanh và không gây ra bất kỳ vấn đề nào mặc dù nó được sử dụng chung trong một ứng dụng lớn.

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 
0

Nó có thể được thực hiện bởi hàm đệ quy

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 

sau đó, ví dụ:

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

lợi nhuận:

NewStr 
some string with many spaces 

Hoặc giải pháp dựa trên phương pháp mô tả bởi @ agdk26 hoặc @Neil Knight (nhưng an toàn r)
cả hai ví dụ trở lại sản lượng trên:

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

hoặc

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ách hoạt động: enter image description here

Chú ý:
Char/chuỗi được sử dụng để thay thế khoảng trống shouldn' t tồn tại khi bắt đầu hoặc kết thúc chuỗi và đứng một mình.

0

Phương pháp # 1

Phương pháp đầu tiên là để thay thế thêm dấu cách giữa các từ với một sự kết hợp biểu tượng phổ biến như một dấu hiệu tạm thời. Sau đó, bạn có thể thay thế các ký hiệu điểm đánh dấu tạm thời bằng cách sử dụng hàm thay thế thay vì một vòng lặp.

Dưới đây là ví dụ về mã thay thế văn bản trong biến Chuỗi.

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

Kiểm tra thời gian thực hiện # 1: Trong thời gian chờ của máy chủ là 1,7 mili giây và tổng thời gian thực hiện là 4,6 mili giây. Kiểm tra thời gian thực hiện # 2: Thời gian chờ trung bình trên các thư trả lời của máy chủ là 1,7 mili giây và tổng thời gian thực hiện là 3,7 mili giây.

Phương pháp # 2

Phương pháp thứ hai không hoàn toàn thanh lịch như trước, nhưng cũng hoàn thành công việc. Phương thức này hoạt động bằng cách lồng bốn (hoặc tùy chọn thêm) thay thế câu lệnh thay thế hai khoảng trắng bằng một khoảng trắng.

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

Thời gian thực hiện thử nghiệm # 1: Trong mười lần chạy của phương pháp thay thế này, thời gian chờ trung bình trên máy chủ trả lời là 1,9 mili giây và tổng thời gian thực hiện là 3,8 mili giây. Kiểm tra thời gian thực hiện # 2: Thời gian chờ trung bình trên các thư trả lời của máy chủ là 1,8 mili giây và tổng thời gian thực hiện là 4,8 mili giây.

Phương pháp # 3

Phương pháp thứ ba thay thế khoảng trắng giữa các từ là sử dụng vòng lặp đơn giản. Bạn có thể thực hiện kiểm tra các khoảng trống thừa trong một vòng lặp while và sau đó sử dụng hàm thay thế để giảm các khoảng trống thừa với mỗi lần lặp của vòng lặp.

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

Thời gian thực hiện kiểm tra # 1: Trong mười lần chạy của phương pháp thay thế này, thời gian chờ trung bình trên máy chủ trả lời là 1,8 mili giây và tổng thời gian thực hiện là 3,4 mili giây. Kiểm tra thời gian thực hiện # 2: Thời gian chờ trung bình trên trả lời của máy chủ là 1,9 mili giây và tổng thời gian thực hiện là 2,8 mili giây.

-3

Bạn có thể thử này:

select Regexp_Replace('single spaces only','(){2,}', ' ') from dual; 
Các vấn đề liên quan