Sayısal olmayan karakterleri bir dizeden nasıl çıkarabilirim?


10

Kullanıcılar bir kutuya bir arama terimi girer ve bu değer saklı bir işleme geçirilir ve veritabanındaki birkaç farklı alana karşı kontrol edilir. Bu alanlar her zaman aynı veri türünde değildir.

Bir alan (telefon numarası) tüm numaralardan oluşur, bu nedenle işaretlenirken .Net CLR işlevi kullanılarak sayısal olmayan tüm karakterler dizeden çıkarılır.

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

Sorun şu ki, bu fonksiyon aniden aşağıdaki hata ile çalışmayı durdurur:

Msg 6533, Seviye 16, Durum 49, Satır 2
AppDomain MyDBName.dbo [çalışma zamanı] .1575, iletme politikası tarafından kaldırıldı. 
uygulamanızın tutarlılığı. Kritik bir kaynağa erişilirken bellek yetersiz oldu.
System.Threading.ThreadAbortException: Tür istisnası 
'System.Threading.ThreadAbortException' atıldı.
System.Threading.ThreadAbortException: 

Bu hata için MSDN'de yayınlanan önerileri denedim , ancak yine de sorunu alıyorum. Şu anda 64 bit sunucuya geçmek bizim için bir seçenek değil.

Sunucuyu yeniden başlatmanın sahip olduğu belleği serbest bıraktığını biliyorum, ancak bu bir üretim ortamında geçerli bir çözüm değil.

Sayısal olmayan karakterleri yalnızca T-SQL kullanarak SQL Server 2005'te bir dizeden ayırmanın bir yolu var mı?

Yanıtlar:


14

Ben bir dize sayısal olmayan karakterleri kaldırmak için çalışan SO bu T-SQL işlevi bulundu .

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

Sorum CLR işlevini kullanmak için bir T-SQL alternatifini soruyordu. Sadece ekstra CLR verilerini gönderdim çünkü yorumlarda istediniz ve sorunu düzeltmenin bir yolunu bildiğinizi düşündüm. CLR yöntemini düzeltmeyi tercih ederdim, ancak araştırmam "düzeltme" nin şu anda benim için kullanılabilir bir seçenek olmayan bir 64 bit sunucuya yükseltmek olduğunu gösterdi. Şimdi sorudaki tüm CLR bilgilerinin yanıltıcı olabileceğini anlıyorum, bu yüzden tamamen sorumdan kaldırdım.
Rachel

Meclisi dağıtmak veya işlevi oluşturmak için kullandığınız yöntemin biraz ipucu verebileceğini düşündüm. "Eskalasyon politikası" güvenlik veya güvenli / güvenli olmayan erişim ile ilgili olabileceğini düşündürdü. Maalesef daha fazla yardım edemem, ancak 32 bit bir sunucuda en iyi T-SQL kullanarak kapalı olabilirsiniz.
Aaron Bertrand

@AaronBertrand Sorun değil, giriş için teşekkürler :) Gelecek yıl veya iki yıl içinde 64 bit sunucuya geçmeyi umuyoruz, bu yüzden umarım bu CLR hatasını tamamen temizlemelidir.
Rachel

0

Bu çözümden oldukça eminim. Performans konusunda emin değilim, ancak bu yaklaşımla ilgili herhangi bir görüş kesinlikle kabul edilir! Temelde karakterin ASCII değeri '0' ve '9' ASCII değerleri arasındaysa @String dizesindeki her karakter için saklayın, aksi takdirde boş bırakın.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.