SQL Server: как удалить пунктуацию с поля? - PullRequest
11 голосов
/ 30 ноября 2009

Кто-нибудь знает хороший способ удалить пунктуацию из поля в SQL Server?

Я думаю

UPDATE tblMyTable SET FieldName = REPLACE(REPLACE(REPLACE(FieldName,',',''),'.',''),'''' ,'')

но это кажется немного утомительным, когда я собираюсь удалить большое количество различных символов, например:! @ # $% ^ & * () <>: "

Заранее спасибо

Ответы [ 8 ]

16 голосов
/ 30 ноября 2009

В идеале вы должны делать это на языке приложения, таком как C # + LINQ, как упомянуто выше.

Если вы хотите сделать это исключительно в T-SQL, то одним из способов сделать это будет создание таблицы, содержащей все знаки препинания, которые вы хотели удалить.

CREATE TABLE Punctuation 
(
    Symbol VARCHAR(1) NOT NULL
)

INSERT INTO Punctuation (Symbol) VALUES('''')
INSERT INTO Punctuation (Symbol) VALUES('-')
INSERT INTO Punctuation (Symbol) VALUES('.')

Затем вы можете создать функцию в SQL для удаления всех символов пунктуации из входной строки.

CREATE FUNCTION dbo.fn_RemovePunctuation
(
    @InputString VARCHAR(500)
)
RETURNS VARCHAR(500)
AS
BEGIN
    SELECT
        @InputString = REPLACE(@InputString, P.Symbol, '')
    FROM 
        Punctuation P

    RETURN @InputString
END
GO

Тогда вы можете просто вызвать функцию в своем выражении UPDATE

UPDATE tblMyTable SET FieldName = dbo.fn_RemovePunctuation(FieldName)
9 голосов
/ 21 апреля 2011

Я хотел избежать создания таблицы и хотел удалить все, кроме букв и цифр.

DECLARE @p int
DECLARE @Result Varchar(250)
DECLARE @BadChars Varchar(12)
SELECT @BadChars = '%[^a-z0-9]%'
-- to leave spaces - SELECT @BadChars = '%[^a-z0-9] %'

SET @Result = @InStr

SET @P =PatIndex(@BadChars,@Result)
WHILE @p > 0 BEGIN
    SELECT @Result = Left(@Result,@p-1) + Substring(@Result,@p+1,250)
    SET @P =PatIndex(@BadChars,@Result)
    END
6 голосов
/ 30 ноября 2009

Я предлагаю 2 решения

Решение 1. Составьте таблицу шумов и замените шумы пробелами

, например

DECLARE @String VARCHAR(MAX)
DECLARE @Noise TABLE(Noise VARCHAR(100),ReplaceChars VARCHAR(10))
SET @String = 'hello! how * > are % u (: . I am ok :). Oh nice!'

INSERT INTO @Noise(Noise,ReplaceChars)
SELECT '!',SPACE(1) UNION ALL SELECT '@',SPACE(1) UNION ALL
SELECT '#',SPACE(1) UNION ALL SELECT '$',SPACE(1) UNION ALL
SELECT '%',SPACE(1) UNION ALL SELECT '^',SPACE(1) UNION ALL
SELECT '&',SPACE(1) UNION ALL SELECT '*',SPACE(1) UNION ALL
SELECT '(',SPACE(1) UNION ALL SELECT ')',SPACE(1) UNION ALL
SELECT '{',SPACE(1) UNION ALL SELECT '}',SPACE(1) UNION ALL
SELECT '<',SPACE(1) UNION ALL SELECT '>',SPACE(1) UNION ALL
SELECT ':',SPACE(1)

SELECT @String = REPLACE(@String, Noise, ReplaceChars) FROM @Noise
SELECT @String Data

Решение 2: С таблицей чисел

DECLARE @String VARCHAR(MAX)
SET @String = 'hello! & how * > are % u (: . I am ok :). Oh nice!'

;with numbercte as
(
 select 1 as rn
 union all
 select rn+1 from numbercte where rn<LEN(@String)
)
select REPLACE(FilteredData,'&#x20;',SPACE(1)) Data from 
(select SUBSTRING(@String,rn,1) 
from numbercte  
where SUBSTRING(@String,rn,1) not in('!','*','>','<','%','(',')',':','!','&','@','#','$')

for xml path(''))X(FilteredData)

Вывод (в обоих случаях)

Данные

hello  how   are  u  . I am ok . Oh nice

Примечание. Я только что добавил несколько шумов. Вам может понадобиться поставить нужные вам шумы.

Надеюсь, это поможет

3 голосов
/ 30 ноября 2009

Вы можете использовать регулярные выражения в SQL Server - вот статья на основе SQL 2005:

http://msdn.microsoft.com/en-us/magazine/cc163473.aspx

1 голос
/ 30 ноября 2009

Я бы обернул его в простой скалярный UDF, чтобы вся очистка строк была в одном месте, если она понадобится снова.

Тогда вы можете использовать его и на INSERT ...

0 голосов
/ 20 июня 2018

Я взял решение Кена MC и превратил его в функцию, которая может заменить все знаки препинания на заданную строку:

----------------------------------------------------------------------------------------------------------------
-- This function replaces all punctuation in the given string with the "replaceWith" string
----------------------------------------------------------------------------------------------------------------
IF object_id('[dbo].[fnReplacePunctuation]') IS NOT NULL
BEGIN
    DROP FUNCTION [dbo].[fnReplacePunctuation];
END;
GO
CREATE FUNCTION [dbo].[fnReplacePunctuation] (@string NVARCHAR(MAX), @replaceWith NVARCHAR(max))
RETURNS NVARCHAR(MAX)
BEGIN
    DECLARE @Result Varchar(max) = @string;
    DECLARE @BadChars Varchar(12) = '%[^a-z0-9]%'; -- to leave spaces - SELECT @BadChars = '%[^a-z0-9] %'
    DECLARE @p int = PatIndex(@BadChars,@Result);
    DECLARE @searchFrom INT;
    DECLARE @indexOfPunct INT = @p;

    WHILE @indexOfPunct > 0 BEGIN
      SET @searchFrom = LEN(@Result) - @p;
      SET @Result = Left(@Result, @p-1) + @replaceWith + Substring(@Result, @p+1,LEN(@Result));
      SET @IndexOfPunct = PatIndex(@BadChars, substring(@Result, (LEN(@Result) - @SearchFrom)+1, LEN(@Result)));
      SET @p = (LEN(@Result) - @searchFrom) + @indexOfPunct;
    END
    RETURN @Result;
END;
GO
-- example:
SELECT dbo.fnReplacePunctuation('This is, only, a tést-really..', '');

Выход:

Thisisonlyatéstreally
0 голосов
/ 21 января 2011

Разве вы не можете использовать PATINDEX для включения только НОМЕРОВ и БУКВ вместо того, чтобы пытаться угадать, какие знаки препинания могут быть в поле? (Не пытаясь быть хитрым, если бы у меня был готов код, я бы поделился им ... но это то, что я ищу).

Похоже, вам нужно создать пользовательскую функцию, чтобы избежать гигантского списка функций замены в ваших запросах - вот хороший пример:

http://www.codeproject.com/KB/database/SQLPhoneNumbersPart_2.aspx?display=Print

0 голосов
/ 30 ноября 2009

Если это одноразовая вещь, я бы использовал фрагмент кода C # + LINQ в LINQPad для работы с регулярными выражениями.

Это быстро и легко, и вам не нужно проходить процедуру настройки хранимой процедуры CLR, а затем выполнять очистку после себя.

...