Ответ 1
Даже более аккуратный:
select string = replace(replace(replace(' select single spaces',' ','<>'),'><',''),'<>',' ')
Вывод:
выберите отдельные пробелы
Мне нужно убедиться, что в заданном поле не более одного пространства (меня не интересует все пробел, просто пробел) между символами.
Итак,
'single spaces only'
необходимо преобразовать в
'single spaces only'
Ниже не будет работать
select replace('single spaces only',' ',' ')
поскольку это приведет к
'single spaces only'
Я бы предпочел использовать собственный T-SQL, а не решение на основе CLR.
Мысли?
Даже более аккуратный:
select string = replace(replace(replace(' select single spaces',' ','<>'),'><',''),'<>',' ')
Вывод:
выберите отдельные пробелы
Это будет работать:
declare @test varchar(100)
set @test = 'this is a test'
while charindex(' ',@test ) > 0
begin
set @test = replace(@test, ' ', ' ')
end
select @test
Если вы знаете, что не должно быть больше определенного количества пробелов в строке, вы можете просто вложить замену:
replace(replace(replace(replace(myText,' ',' '),' ',' '),' ',' '),' ',' ')
4 замены должны исправить до 16 последовательных пробелов (16, затем 8, затем 4, затем 2, затем 1)
Если это может быть значительно дольше, вам нужно сделать что-то вроде встроенной функции:
CREATE FUNCTION strip_spaces(@str varchar(8000))
RETURNS varchar(8000) AS
BEGIN
WHILE CHARINDEX(' ', @str) > 0
SET @str = REPLACE(@str, ' ', ' ')
RETURN @str
END
Тогда просто сделайте
SELECT dbo.strip_spaces(myText) FROM myTable
update mytable
set myfield = replace (myfield, ' ', ' ')
where charindex(' ', myfield) > 0
Заменить будет работать во всех двойных пространствах, не нужно ставить несколько замен. Это решение на основе набора.
Это несколько грубая сила, но будет работать
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
Это можно сделать рекурсивно через функцию:
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
тогда, например:
SELECT dbo.RemSpaceFromStr('some string with many spaces') AS NewStr
возвращает:
NewStr
some string with many spaces
Или решение, основанное на методе, описанном @agdk26 или @Neil Knight (но безопаснее)
оба примера возвращают вывод выше:
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...
или же
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
Внимание:
Символ/строка, используемые для замены пробелов, не должны существовать в начале или конце строки и стоять отдельно.
Вот простая функция, которую я создал для очистки пробелов до или после, и несколько пробелов внутри строки. Он грациозно обрабатывает до 108 пробелов в одном растяжке и столько блоков, сколько в строке. Вы можете увеличить это в 8 раз, добавив дополнительные строки с большими кусками пространств, если вам нужно. Он работает быстро и не вызвал никаких проблем, несмотря на его обобщенное использование в большом приложении.
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
Это решение через множественную замену, которая работает для любых строк (не требует специальных символов, которые не являются частью строки).
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'
Нашел это, копая для ответа:
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
Полный ответ (с объяснением) был вырван из: http://techtipsbysatish.blogspot.com/2010/08/sql-server-replace-multiple-spaces-with.html
При втором взгляде кажется немного отличающейся версией выбранного ответа.
Метод # 1
Первый способ - заменить лишние пробелы между словами с необычной символической комбинацией в качестве временного маркера. Затем вы можете заменить временные символы маркера, используя функцию replace, а не цикл.
Вот пример кода, который заменяет текст в переменной String.
DECLARE @testString AS VARCHAR(256) = ' Test text with random* spacing. Please normalize this spacing!';
SELECT REPLACE(REPLACE(REPLACE(@testString, ' ', '*^'), '^*', ''), '*^', ' ');
Время выполнения выполнения №1: в десяти прогонах этого метода замены среднее время ожидания ответов сервера составляло 1,7 миллисекунды, а общее время выполнения составляло 4,6 миллисекунды. Время выполнения теста №2: среднее время ожидания ответов сервера составляло 1,7 миллисекунды, а общее время выполнения составляло 3,7 миллисекунды.
Метод # 2
Второй метод не столь изящный, как первый, но и выполняет свою работу. Этот метод работает путем вложения четырех (или необязательно большего) замещающих операторов, которые заменяют два пробела одним пробелом.
DECLARE @testString AS VARCHAR(256) = ' Test text with random* spacing. Please normalize this spacing!';
SELECT REPLACE(REPLACE(REPLACE(REPLACE(@testString,' ',' '),' ',' '),' ',' '),' ',' ')
Тест времени выполнения # 1: в десяти прогонах этого метода замены среднее время ожидания ответов сервера составляло 1,9 миллисекунды, а общее время выполнения составляло 3,8 миллисекунды. Время выполнения теста №2: среднее время ожидания ответов сервера составляло 1,8 миллисекунды, а общее время выполнения составляло 4,8 миллисекунды.
Метод № 3
Третий способ замены лишних пробелов между словами - использовать простой цикл. Вы можете выполнить проверку дополнительных пробелов в цикле while, а затем использовать функцию replace, чтобы уменьшить дополнительные пробелы с каждой итерацией цикла.
DECLARE @testString AS VARCHAR(256) = ' Test text with random* spacing. Please normalize this spacing!';
WHILE CHARINDEX(' ',@testString) > 0
SET @testString = REPLACE(@testString, ' ', ' ')
SELECT @testString
Тест времени выполнения # 1: в десяти прогонах этого метода замены среднее время ожидания ответов сервера составляло 1,8 миллисекунды, а общее время выполнения составляло 3,4 миллисекунды. Время выполнения теста №2: среднее время ожидания ответов сервера составляло 1,9 миллисекунды, а общее время выполнения составляло 2,8 миллисекунды.
Я использую решение FOR XML PATH для замены нескольких пробелов в один пробел
Идея состоит в том, чтобы заменить пробелы тегами XML. Затем разбить строку XML на строковые фрагменты без тегов XML. Наконец, объединить эти строковые значения, добавив один пробел между двумя
Вот как можно вызывать финальную функцию UDF
select dbo.ReplaceMultipleSpaces(' Sample text with multiple space ')
DECLARE @str varchar(150)
SET @str='Hello My name is Jiyaul mustafa'
Select REPLACE(REPLACE(REPLACE(@str,' ','{}'),'}{',''),'{}',' ')
Я обычно использую этот подход:
declare @s varchar(50)
set @s = 'TEST TEST'
select REPLACE(REPLACE(REPLACE(@s,' ','[o][c]'),'[c][o]',''),'[o][c]',' ')
Вы можете попробовать следующее:
select Regexp_Replace('single spaces only','( ){2,}', ' ') from dual;
update mytable
set myfield = replace(myfield, ' ', ' ')
where myfield like '% %'
Попробуйте это.