Убрать специальные символы в SQL без цикла? - PullRequest
9 голосов
/ 12 декабря 2011

Есть ли способ вырезать специальные символы (оставляя только буквенно-цифровые) из строки / поля на SQL-сервере без цикла / пользовательской функции?

Пока что лучшее, что я придумал, это:

Create Function [dbo].[strip_special](@Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
    While PatIndex('%[^a-z0-9]%', @Temp) > 0
        Set @Temp = Stuff(@Temp, PatIndex('%[^a-z0-9]%', @Temp), 1, '')
    Return @TEmp
End

На некоторых серверах у меня нет привилегий для добавления пользовательских функций, поэтому я хотел бы достичь того же результата без.У меня также есть опасения по поводу эффективности / производительности цикла (хотя я думаю, что даже встроенная функция / метод, вероятно, сама использовала бы цикл).

Спасибо

Ответы [ 3 ]

7 голосов
/ 12 декабря 2011

Я полагаю, у вас есть столбец, который вы хотите заменить, вот как вы могли бы это сделать:

 declare @table table(id int, temp varchar(15))


insert @table values(1, 'abc-.123+')
insert @table values(2, '¤%&(abc-.?=&(/#')

;with t1 as
(
select temp a, id from @table
union all
select cast(replace(a, substring(a, PatIndex('%[^a-z0-9]%', a), 1), '') as varchar(15)), id
from t1
where PatIndex('%[^a-z0-9]%', a) > 0
)
select t2.*, t1.a from t1
join @table t2
on t1.id = t2.id
where PatIndex('%[^a-z0-9]%', a) = 0
option (maxrecursion 0)

Результат:

id          temp            a
----------- --------------- ---------------
2           ¤%&(abc-.?=&(/# abc
1           abc-.123+       abc123
1 голос
/ 12 декабря 2011

Если вы хотите сделать это быстрее, используйте эту функцию.

Если вам нужно использовать ее без функции, вам может потребоваться использовать курсоры для выборки каждой строки за раз и применения содержимогоследующая функция для каждой строки.

create function dbo.strip_special(@s varchar(256)) returns varchar(256)
   with schemabinding
begin
   if @s is null
      return null
   declare @s2 varchar(256)
   set @s2 = ''
   declare @l int
   set @l = len(@s)
   declare @p int
   set @p = 1
   while @p <= @l begin
      declare @c int
      set @c = ascii(substring(@s, @p, 1))
      if @c between 48 and 57 or @c between 65 and 90 or @c between 97 and 122
         set @s2 = @s2 + char(@c)
      set @p = @p + 1
      end
   if len(@s2) = 0
      return null
   return @s2

   end
0 голосов
/ 24 октября 2013

Помимо того, что у меня есть куча вложенных операторов REPLACE, это лучшее, что я могу придумать. У нас есть многоязычное требование, поэтому возвращение буквенно-цифровых символов не работает для таких языков, как арабский

 DECLARE
    @OrgString  nVarchar(max),
    @Pattern    nvarchar(max)


SET @OrgString = N'~,`,!,@,#,$,%,^,&,*,(,),0-9,_,-,+,=,[,],{,},;,:,",<,>,?,/,\,|حساب "خارج الميز1$انية"'
SET @Pattern = '%[~,`,!,@,#,$,%,^,&,*,(,),0-9,_,''-,+,=,[,{,},;,:,",<,>,?,/,\,|]%'


WHILE PATINDEX( @Pattern, @OrgString ) > 0 
    SET @OrgString = REPLACE( @OrgString, SUBSTRING( @OrgString, PATINDEX( @Pattern, @OrgString ), 1 ), '')
SELECT REPLACE(@OrgString, ']', '') -- Cant workout how to put ] in @Pattern
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...