Como posso retirar caracteres não numéricos de uma string?

10

Os usuários inserem um termo de pesquisa em uma caixa e esse valor é passado para um procedimento armazenado e verificado em alguns campos diferentes no banco de dados. Esses campos nem sempre são do mesmo tipo de dados.

Um campo (número de telefone) consiste em todos os números; portanto, ao marcá-lo, todos os caracteres não numéricos são removidos da string usando uma função .Net CLR.

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

O problema é que essa função para abruptamente para de funcionar ocasionalmente com o seguinte erro:

Msg 6533, nível 16, estado 49, linha 2
O AppDomain MyDBName.dbo [tempo de execução] .1575 foi descarregado pela política de escalação para garantir que o 
consistência do seu aplicativo. A falta de memória ocorreu ao acessar um recurso crítico.
System.Threading.ThreadAbortException: exceção do tipo 
'System.Threading.ThreadAbortException' foi lançado.
System.Threading.ThreadAbortException: 

Tentei as sugestões postadas no MSDN para esse erro, mas ainda estou recebendo o problema. No momento, mudar para um servidor de 64 bits não é uma opção para nós.

Sei que reiniciar o servidor libera qualquer memória que tenha, mas essa não é uma solução viável em um ambiente de produção.

Existe uma maneira de remover caracteres não numéricos de uma seqüência de caracteres no SQL Server 2005 usando apenas T-SQL?

Rachel
fonte

Respostas:

14

Encontrei essa função T-SQL no SO que funciona para remover caracteres não numéricos de uma string.

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
fonte
Minha pergunta estava pedindo uma alternativa T-SQL para usar a função CLR. Eu publiquei apenas os dados extras do CLR porque você os solicitou nos comentários e achei que sabia uma maneira de corrigir o problema. Prefiro corrigir o método CLR, no entanto, minha pesquisa mostrou que a "correção" é atualizar para um servidor de 64 bits, o que não é uma opção disponível para mim no momento. Percebo agora que todas as informações de CLR na pergunta podem ser enganosas, por isso a removi totalmente da minha pergunta.
19412 Rachel
Eu pensei que talvez o método que você usou para implantar a montagem ou criar a função possa render alguma pista. A "política de escalonamento" me fez pensar que poderia ter algo a ver com segurança ou acesso seguro / não seguro. Desculpe, não posso ajudar mais, mas em um servidor de 32 bits é melhor usar o T-SQL.
Aaron Bertrand
@AaronBertrand Não há problema, obrigado pela entrada :) Esperamos mudar para um servidor de 64 bits dentro de um ou dois anos, espero que isso resolva completamente o erro CLR.
19412 Rachel
0

Estou bastante confiante nesta solução. Não tenho certeza sobre desempenho, mas qualquer opinião sobre essa abordagem é definitivamente bem-vinda! Basicamente, para cada caractere na sequência @String, se o valor ASCII do caractere estiver entre os valores ASCII de '0' e '9', mantenha-o; caso contrário, substitua-o por um espaço em branco.

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
fonte