Làm cách nào tôi có thể tách các ký tự không phải là số ra khỏi chuỗi?


10

Người dùng nhập cụm từ tìm kiếm vào một hộp và giá trị đó được chuyển đến một thủ tục được lưu trữ và được kiểm tra đối với một vài trường khác nhau trong cơ sở dữ liệu. Các trường này không phải luôn luôn có cùng kiểu dữ liệu.

Một trường (số điện thoại) bao gồm tất cả các số, vì vậy khi kiểm tra nó sẽ loại bỏ tất cả các ký tự không phải là số từ chuỗi bằng hàm .Net CLR.

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

Vấn đề là, chức năng này đột ngột ngừng hoạt động trong trường hợp có lỗi sau:

Msg 6533, Cấp 16, Bang 49, Dòng 2
AppDomain MyDBName.dbo [runtime] .1575 đã được tải bằng chính sách leo thang để đảm bảo 
tính nhất quán của ứng dụng của bạn. Hết bộ nhớ xảy ra trong khi truy cập một tài nguyên quan trọng.
System.Threading.ThreadAdortException: Ngoại lệ của loại 
'System.Threading.ThreadAdortException' đã bị ném.
System.Threading.ThreadAdortException: 

Tôi đã thử các đề xuất được đăng trên MSDN cho lỗi này, nhưng vẫn gặp sự cố. Tại thời điểm này, chuyển sang máy chủ 64 bit không phải là một lựa chọn cho chúng tôi.

Tôi biết khởi động lại máy chủ sẽ giải phóng bất kỳ bộ nhớ nào mà nó đã giữ, nhưng đó không phải là giải pháp khả thi trong môi trường sản xuất.

Có cách nào để loại bỏ các ký tự không phải là số trong chuỗi trong SQL Server 2005 chỉ bằng T-SQL không?

Câu trả lời:


14

Tôi đã tìm thấy hàm T-SQL này trên SO hoạt động để loại bỏ các ký tự không phải là số khỏi chuỗi.

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

Câu hỏi của tôi là yêu cầu một giải pháp thay thế T-SQL để sử dụng hàm CLR. Tôi chỉ đăng thêm dữ liệu CLR vì bạn đã yêu cầu nó trong các bình luận và tôi nghĩ bạn biết cách khắc phục vấn đề. Tôi muốn sửa phương pháp CLR, tuy nhiên nghiên cứu của tôi đã chỉ ra rằng "cách khắc phục" là nâng cấp lên máy chủ 64 bit, đây không phải là một tùy chọn có sẵn cho tôi tại thời điểm này. Bây giờ tôi nhận ra rằng tất cả thông tin CLR trong câu hỏi có thể gây hiểu nhầm, vì vậy tôi đã xóa nó hoàn toàn khỏi câu hỏi của mình.
Rachel

Tôi nghĩ rằng có lẽ phương thức bạn đã sử dụng để triển khai lắp ráp hoặc tạo hàm có thể mang lại một số manh mối. "Chính sách nâng mức" khiến tôi nghĩ rằng nó có thể có liên quan đến bảo mật hoặc truy cập an toàn / không an toàn. Xin lỗi tôi không thể giúp đỡ nhiều hơn, nhưng trên máy chủ 32 bit, bạn có thể sử dụng T-SQL tốt nhất thay thế.
Aaron Bertrand

@AaronBertrand Không có vấn đề gì, cảm ơn vì đầu vào :) Chúng tôi hy vọng sẽ chuyển sang máy chủ 64 bit trong vòng một hoặc hai năm tới, vì vậy hy vọng điều đó sẽ xóa hoàn toàn lỗi CLR.
Rachel

0

Tôi khá tự tin vào giải pháp này. Tôi không chắc chắn về hiệu suất nhưng bất kỳ ý kiến ​​về phương pháp này chắc chắn đều được hoan nghênh! Về cơ bản cho mỗi ký tự trong chuỗi @String nếu giá trị ASCII của ký tự nằm giữa các giá trị ASCII là '0' và '9' thì hãy giữ nguyên, thay vào đó bằng một khoảng trống.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.