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.