2011-12-12 22 views
9

¿Hay alguna manera de quitar caracteres especiales (que dejan solo caracteres alfanuméricos) de una cadena/campo en el servidor SQL sin un bucle/función personalizada?¿Eliminar caracteres especiales en SQL sin bucle?

Hasta el momento, el mejor que he llegado con es:

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 

En algunos servidores no tengo los privilegios a CREAD funciones definidas por el usuario y por eso me gustaría ser capaz de lograr el mismo resultado sin. También me preocupa la eficiencia/rendimiento del ciclo (aunque supongo que incluso una función/método incorporado probablemente usaría un ciclo).

Gracias

+1

que he visto soemtimes sugerir desmontaje de cadenas a una tabla como cosa y unirse a una tabla de caracteres keeper . [Aquí hay una discusión en la que podría estar interesado] (http://ask.sqlservercentral.com/questions/75404/strip-all-but-alpha-chars-out-of-a-string) –

Respuesta

6

que se supone que tiene una columna que desea reemplazar, esta es la forma en que podría hacerlo:

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) 

Resultado:

id   temp   a 
----------- --------------- --------------- 
2   ¤%&(abc-.?=&(/# abc 
1   abc-.123+  abc123 
1

Si desea hacerlo más rápido, utilice esta función.

Si necesita usarlo sin una función, puede necesitar usar cursores para buscar cada fila a la vez y aplicar el contenido de la siguiente función para cada fila.

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 
+3

¿Por qué es más rápido? Pensé que tu función tiene que recorrer cada carácter de la entrada, mientras que mi función solo funcionará para cada carácter no alfanumérico. –

+0

Puedes usar tu funtion también. Pero en ese caso, ¿no deberías usar ''% [^ A-Za-z0-9]%'' en lugar de ''% [^ a-z0-9]%''? –

0

Aparte de tener una gran pila de anidado REEMPLAZAR las declaraciones es lo mejor que se me ocurre. Tenemos requisito en varios idiomas por lo que despojar las cosas vuelvan a la alfa-numérico no funciona para idiomas como el árabe

personas
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