Come posso rimuovere caratteri non numerici da una stringa?


10

Gli utenti inseriscono un termine di ricerca in una casella e quel valore viene passato a una procedura memorizzata e confrontato con alcuni campi diversi nel database. Questi campi non sono sempre dello stesso tipo di dati.

Un campo (numero di telefono) è composto da tutti i numeri, quindi quando lo si controlla rimuove tutti i caratteri non numerici dalla stringa utilizzando una funzione CLR .Net.

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

Il problema è che questa funzione smette bruscamente di funzionare occasionalmente con il seguente errore:

Messaggio 6533, livello 16, stato 49, linea 2
AppDomain MyDBName.dbo [runtime] .1575 è stato scaricato dalla politica di escalation per garantire che 
coerenza della tua applicazione. Memoria esaurita durante l'accesso a una risorsa critica.
System.Threading.ThreadAbortException: eccezione di tipo 
È stato generato "System.Threading.ThreadAbortException".
System.Threading.ThreadAbortException: 

Ho provato i suggerimenti pubblicati su MSDN per questo errore, ma sto ancora riscontrando il problema. Al momento, passare a un server a 64 bit non è un'opzione per noi.

So che il riavvio del server rilascia qualsiasi memoria abbia conservato, ma questa non è una soluzione praticabile in un ambiente di produzione.

Esiste un modo per eliminare i caratteri non numerici da una stringa in SQL Server 2005 utilizzando solo T-SQL?

Risposte:


14

Ho trovato questa funzione T-SQL su SO che funziona per rimuovere caratteri non numerici da una stringa.

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

La mia domanda era chiedere un'alternativa T-SQL all'utilizzo della funzione CLR. Ho pubblicato solo i dati CLR aggiuntivi perché tu l'hai richiesto nei commenti e pensavo che tu sapessi un modo per risolvere il problema. Preferirei correggere il metodo CLR, tuttavia la mia ricerca ha dimostrato che la "correzione" è l'aggiornamento a un server a 64 bit, che al momento non è un'opzione disponibile per me. Ora mi rendo conto che tutte le informazioni CLR nella domanda possono essere fuorvianti, quindi le ho rimosse completamente dalla mia domanda.
Rachel,

Ho pensato che forse il metodo che hai usato per distribuire l'assembly o creare la funzione potrebbe dare qualche indizio. La "politica di escalation" mi ha fatto pensare che potrebbe avere qualcosa a che fare con la sicurezza o l'accesso sicuro / non sicuro. Spiacenti, non posso essere di maggiore aiuto, ma su un server a 32 bit potresti invece utilizzare T-SQL.
Aaron Bertrand

@AaronBertrand Nessun problema, grazie per l'input :) Speriamo di passare a un server a 64 bit entro il prossimo anno o due, quindi speriamo che dovrebbe cancellare completamente l'errore CLR.
Rachel,

0

Sono abbastanza fiducioso in questa soluzione. Non sono sicuro delle prestazioni, ma qualsiasi opinione su questo approccio è sicuramente benvenuta! Fondamentalmente per ogni carattere nella stringa @String se il valore ASCII del carattere è compreso tra i valori ASCII di '0' e '9', mantenerlo, altrimenti sostituirlo con uno spazio vuoto.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.