Як я можу знімати нечислові символи з рядка?


10

Користувачі вводять пошуковий термін у поле, і це значення передається у збережену процедуру та перевіряється на кілька різних полів у базі даних. Ці поля не завжди мають один і той же тип даних.

Одне поле (номер телефону) складається з усіх чисел, тому при перевірці воно викреслює всі нечислові символи з рядка за допомогою функції .Net CLR.

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

Проблема полягає в тому, що ця функція різко припиняє роботу з нагоди з наступною помилкою:

Msg 6533, рівень 16, стан 49, рядок 2
AppDomain MyDBName.dbo [runtime] .1575 був завантажений політикою ескалації для забезпечення 
узгодженість вашої заявки. Залишилось пам'яті під час доступу до критичного ресурсу.
System.Threading.ThreadAbortException: Виняток типу 
"System.Threading.ThreadAbortException" було кинуто.
System.Threading.ThreadAbortException: 

Я спробував пропозиції, розміщені на MSDN, щодо цієї помилки, але все ще отримую проблему. Наразі перехід на 64-бітний сервер - це не варіант для нас.

Я знаю, що перезапуск сервера вивільняє незалежну пам'ять, але це не є життєздатним рішенням у виробничих умовах.

Чи є спосіб зняти нечислові символи з рядка в SQL Server 2005 лише з використанням T-SQL?

Відповіді:


14

Я знайшов цю функцію T-SQL на SO, яка працює для видалення нечислових символів з рядка.

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

На моє запитання було запропонувати альтернативу T-SQL використанню функції CLR. Я опублікував лише додаткові дані CLR, тому що ви просили їх у коментарях, і я думав, що ви знаєте спосіб вирішити проблему. Я вважаю за краще виправити метод CLR, однак моє дослідження показало, що «виправити» - це оновлення до 64-бітного сервера, який наразі є недоступним для мене варіантом. Зараз я усвідомлюю, що вся інформація про CLR у запитанні може вводити в оману, тому я повністю її видалив із запитання.
Рейчел

Я думав, що, можливо, метод, який ви використовували для розгортання збірки або створення функції, може дати деяку підказку. "Політика ескалації" змусила мене думати, що це може мати щось спільне з безпекою або безпечним / небезпечним доступом. Вибачте, я не можу допомогти більше, але на 32-розрядному сервері вам може бути найкраще використовувати T-SQL.
Аарон Бертран

@AaronBertrand Немає проблем, дякую за вклад :) Ми сподіваємось перейти на 64-бітний сервер протягом найближчих року-двох, тому, сподіваємось, це має повністю усунути помилку CLR.
Рейчел

0

Я досить впевнений у цьому рішенні. Я не впевнений у виконанні, але будь-які думки щодо цього підходу, безумовно, вітаються! В основному для кожного символу в рядку @String, якщо значення ASCII символу знаходиться між значеннями ASCII '0' та '9', тоді зберігайте його, інакше замініть його порожнім.

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.