it-swarm-eu.dev

Jak lze z řetězce odstranit nečíselné znaky?

Uživatelé zadají hledaný výraz do pole a tato hodnota bude předána uložené proceduře a zkontrolována proti několika různým polím v databázi. Tato pole nejsou vždy stejného typu dat.

Jedno pole (telefonní číslo) se skládá ze všech čísel, takže při jeho kontrole se pomocí funkce .Net CLR odstraní všechny nečíselné znaky z řetězce.

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

Problém je, že tato funkce náhle přestane pracovat příležitostně s následující chybou:

 Zpráva 6533, úroveň 16, stav 49, řádek 2 
 AppDomain MyDBName.dbo [runtime] .1575 byla uvolněna zásadou eskalace, aby byla zajištěna konzistence 
 Vaší aplikace. Při přístupu ke kritickému prostředku došlo k nedostatku paměti. 
 System.Threading.ThreadAbortException: Výjimka typu 
 'System.Threading.ThreadAbortException' byla vyvolána. 
 System.Threading.ThreadAbortException: 

Vyzkoušel jsem návrhy zveřejněné pro MSDN pro tuto chybu, ale stále se mi problém dostává. V tuto chvíli pro nás není přechod na 64bitový server možností.

Vím, že restartování serveru uvolní jakoukoli paměť, kterou má, ale v produkčním prostředí to není proveditelné řešení.

Existuje způsob, jak odstranit nečíselné znaky z řetězce v SQL Server 2005 pouze pomocí T-SQL?

10
Rachel

Našel jsem tato funkce T-SQL on SO, která pracuje na odstranění nečíselných znaků z řetězce.

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
14
Rachel

Jsem si v tomto řešení docela jistý. Nejsem si jistý výkonem, ale jakékoli názory na tento přístup jsou rozhodně vítány! V podstatě pro každý znak v řetězci @String, pokud je hodnota ASCII hodnota znaku mezi ASCII hodnoty '0' a '9'), pak si jej ponechte , jinak jej nahraďte prázdným.

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
0
mateoc15