¿Cómo puedo quitar caracteres no numéricos de una cadena?

10

Los usuarios ingresan un término de búsqueda en un cuadro, y ese valor se pasa a un procedimiento almacenado y se compara con algunos campos diferentes en la base de datos. Estos campos no siempre son del mismo tipo de datos.

Un campo (número de teléfono) consta de todos los números, por lo que, al marcarlo, elimina todos los caracteres no numéricos de la cadena utilizando una función .Net CLR.

SELECT dbo.RegexReplace('(123)123-4567', '[^0-9]', '')

El problema es que esta función deja de funcionar abruptamente en ocasiones con el siguiente error:

Msg 6533, Nivel 16, Estado 49, Línea 2
AppDomain MyDBName.dbo [tiempo de ejecución] .1575 se descargó mediante la política de escalación para garantizar que 
Consistencia de su aplicación. La falta de memoria ocurrió al acceder a un recurso crítico.
System.Threading.ThreadAbortException: excepción de tipo 
Se lanzó 'System.Threading.ThreadAbortException'.
System.Threading.ThreadAbortException: 

He probado las sugerencias publicadas en MSDN para este error, pero sigo teniendo el problema. En este momento, cambiar a un servidor de 64 bits no es una opción para nosotros.

Sé que reiniciar el servidor libera la memoria que haya tenido, pero esa no es una solución viable en un entorno de producción.

¿Hay alguna forma de quitar caracteres no numéricos de una cadena en SQL Server 2005 usando solo T-SQL?

Rachel
fuente

Respuestas:

14

Encontré esta función T-SQL en SO que funciona para eliminar caracteres no numéricos de una cadena.

CREATE Function [fnRemoveNonNumericCharacters](@strText VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
BEGIN
    WHILE PATINDEX('%[^0-9]%', @strText) > 0
    BEGIN
        SET @strText = STUFF(@strText, PATINDEX('%[^0-9]%', @strText), 1, '')
    END
    RETURN @strText
END
Rachel
fuente
Mi pregunta fue pedir una alternativa T-SQL para usar la función CLR. Solo publiqué los datos adicionales de CLR porque lo solicitó en los comentarios, y pensé que conocía una forma de solucionar el problema. Prefiero arreglar el método CLR, sin embargo, mi investigación ha demostrado que la "solución" es actualizar a un servidor de 64 bits, que no es una opción disponible para mí en este momento. Ahora me doy cuenta de que toda la información de CLR en la pregunta puede ser engañosa, por lo que la eliminé por completo de mi pregunta.
Rachel
Pensé que tal vez el método que utilizó para implementar el ensamblaje o crear la función podría dar alguna pista. La "política de escalamiento" me hizo pensar que podría tener algo que ver con la seguridad o el acceso seguro / inseguro. Lo siento, no puedo ser de más ayuda, pero en un servidor de 32 bits es mejor que uses T-SQL.
Aaron Bertrand
@AaronBertrand No hay problema, gracias por el aporte :) Esperamos pasar a un servidor de 64 bits en el próximo año o dos, así que espero que eso aclare completamente el error CLR.
Rachel
0

Tengo bastante confianza en esta solución. No estoy seguro sobre el rendimiento, ¡pero cualquier opinión sobre este enfoque es definitivamente bienvenida! Básicamente para cada carácter en la cadena @String si el valor ASCII del carácter está entre los valores ASCII de '0' y '9', entonces manténgalo, de lo contrario reemplácelo con un espacio en blanco.

CREATE FUNCTION [dbo].[fnStripNonNumerics](
             @String VARCHAR(500))
RETURNS VARCHAR(1000)
AS
BEGIN
    DECLARE
          @n INT = 1,
          @Return VARCHAR(100) = ''

    WHILE @n <= LEN(@String)
       BEGIN
          SET @Return = @Return + CASE
                             WHEN ASCII(SUBSTRING(@String, @n, 1)) BETWEEN ASCII('0') AND ASCII('9')
                                THEN SUBSTRING(@String, @n, 1)
                                ELSE ''
                             END
          SET @n = @n + 1
       END

    RETURN CASE
         WHEN @Return = ''
            THEN NULL
            ELSE @Return
         END
END
mateoc15
fuente