Jak mogę usunąć znaki nienumeryczne z ciągu?

10

Użytkownicy wpisują wyszukiwane hasło w polu, a ta wartość jest przekazywana do procedury składowanej i sprawdzana względem kilku różnych pól w bazie danych. Te pola nie zawsze są tego samego typu danych.

Jedno pole (numer telefonu) składa się ze wszystkich cyfr, więc podczas sprawdzania usuwa wszystkie znaki nienumeryczne z ciągu za pomocą funkcji .Net CLR.

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

Problem polega na tym, że funkcja ta nagle przestaje działać z powodu następującego błędu:

Msg 6533, poziom 16, stan 49, wiersz 2
AppDomain MyDBName.dbo [środowisko wykonawcze] .1575 zostało zwolnione przez zasady eskalacji, aby zapewnić 
spójność twojej aplikacji. Brak dostępu wystąpił podczas uzyskiwania dostępu do zasobu krytycznego.
System.Threading.ThreadAbortException: Wyjątek typu 
Zgłoszono „System.Threading.ThreadAbortException”.
System.Threading.ThreadAbortException: 

Wypróbowałem sugestie opublikowane w witrynie MSDN dotyczące tego błędu, ale nadal pojawia się problem. W tej chwili przejście na serwer 64-bitowy nie jest dla nas opcją.

Wiem, że ponowne uruchomienie serwera zwalnia posiadaną pamięć, ale nie jest to realne rozwiązanie w środowisku produkcyjnym.

Czy istnieje sposób na usunięcie znaków nienumerycznych z ciągu w SQL Server 2005 przy użyciu tylko T-SQL?

Rachel
źródło

Odpowiedzi:

14

Znalazłem tę funkcję T-SQL na SO, która działa w celu usunięcia znaków nienumerycznych z ciągu.

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
źródło
Moje pytanie dotyczyło alternatywy T-SQL do korzystania z funkcji CLR. Dodałem tylko dodatkowe dane CLR, ponieważ poprosiłeś o to w komentarzach i myślałem, że znasz sposób na rozwiązanie tego problemu. Wolałbym naprawić metodę CLR, jednak moje badania wykazały, że „poprawka” polega na uaktualnieniu do serwera 64-bitowego, co obecnie nie jest dla mnie dostępną opcją. Teraz zdaję sobie sprawę, że wszystkie informacje CLR w pytaniu mogą wprowadzać w błąd, dlatego całkowicie usunąłem je z mojego pytania.
Rachel
Pomyślałem, że być może metoda zastosowana do wdrożenia zestawu lub utworzenia funkcji może dać jakąś wskazówkę. „Polityka eskalacji” sprawiła, że ​​pomyślałem, że może to mieć związek z bezpieczeństwem lub dostępem bezpiecznym / niebezpiecznym. Przykro mi, ale nie mogę pomóc, ale na serwerze 32-bitowym najlepiej jest użyć T-SQL.
Aaron Bertrand
@AaronBertrand Nie ma problemu, dziękuję za dane wejściowe :) Mamy nadzieję przenieść się na serwer 64-bitowy w ciągu najbliższego roku lub dwóch, więc mam nadzieję, że powinno to całkowicie usunąć błąd CLR.
Rachel,
0

Jestem dość pewny tego rozwiązania. Nie jestem pewien co do wydajności, ale wszelkie opinie na temat tego podejścia są zdecydowanie mile widziane! Zasadniczo dla każdego znaku w ciągu @String, jeśli wartość ASCII znaku mieści się między wartościami ASCII „0” i „9”, należy go zachować, w przeciwnym razie zastąp go pustym.

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
źródło