Как я могу удалить нечисловые символы из строки?

10

Пользователи вводят поисковый термин в поле, и это значение передается в хранимую процедуру и проверяется по нескольким различным полям в базе данных. Эти поля не всегда имеют одинаковый тип данных.

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

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

Проблема в том, что эта функция внезапно перестает работать при следующей ошибке:

Сообщение 6533, уровень 16, состояние 49, строка 2
AppDomain MyDBName.dbo [время выполнения] .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
mateoc15
источник