Nếu bạn được đảm bảo chỉ sử dụng 26 chữ cái trong bảng chữ cái tiếng Anh Hoa Kỳ (cả phiên bản chữ hoa và chữ thường) thì bạn có thể tránh sử dụng LIKE
và / hoặc PATINDEX
với ký hiệu phạm vi đơn giản [a-z]
(bạn sẽ không cần sử dụng chữ "Z" viết hoa khi sử dụng Collation không phân biệt chữ hoa chữ thường).
Nhưng, nếu bạn có thể nhận được các ký tự không tìm thấy trong bảng chữ cái en-US có sẵn trong nhiều Trang mã / Bộ sưu tập VARCHAR
dữ liệu khác nhau (ví dụ: Þ
chữ hoa "Thorn" = SELECT CHAR(0xDE)
), thì bạn có thể cần đưa các ký tự đó vào lớp ký tự : [a-z0-9, Þ]
. Tất nhiên, những ký tự phụ đó sẽ là gì trên cơ sở Trang theo Mã.
Ngoài ra, xin lưu ý rằng cả loại Collation (SQL Server so với Windows) và cài đặt độ nhạy (trường hợp, dấu, v.v. nhạy cảm và không nhạy cảm) sẽ ảnh hưởng đến các ký tự được bao gồm trong một phạm vi cụ thể. Ví dụ: Bộ sưu tập SQL Server sắp xếp các chữ cái viết hoa và viết thường theo thứ tự ngược lại là Bộ sưu tập Windows. Có nghĩa là, giả sử Collation phân biệt chữ hoa chữ thường cho cả hai loại Collations, một loại sẽ làm AaBb...
và loại kia sẽ làm aAbB...
. Hiệu quả sẽ là a
trong phạm vi của A-Z
một trong số họ, nhưng không phải là một trong số họ. Và phạm vi a-Z
sẽ không khớp với bất kỳ ký tự nào trong Collation nhị phân (một kết thúc bằng một _BIN
hoặc _BIN2
, nhưng không sử dụng _BIN
) với giá trị A
là 65 vàa
là 97, do đó, nó là một phạm vi không hợp lệ từ 97 đến 65 ;-). Có quá nhiều biến thể để đưa ra ví dụ cho ở đây vì vậy tôi sẽ cố gắng đăng một lời giải thích chi tiết trên blog của mình vào lúc nào đó (và sau đó sẽ cập nhật thông tin này với liên kết đến nó). Tuy nhiên, nếu bạn sẽ nghiêm ngặt về việc chỉ chấp nhận các ký tự tiếng Anh Hoa Kỳ (ngay cả khi bạn có thể nhận được các chữ cái hợp lệ từ các ngôn ngữ khác) thì tùy chọn tốt nhất của bạn có thể sẽ là sử dụng mẫu và Đối chiếu sau:
LIKE '%[^A-Za-z0-9, ]%' COLLATE Latin1_General_100_BIN2
Bây giờ, nếu bạn đang hỗ trợ NVARCHAR
dữ liệu và có thể nhận các ký tự "từ" từ nhiều ngôn ngữ khác nhau, thì T-SQL sẽ không giúp ích nhiều vì nó không có cách nào thực sự để phân biệt những điều này. Trong trường hợp này, bạn nên sử dụng Biểu thức chính quy (RegEx) - cụ thể là Replace
phương thức / hàm - và những phương thức này chỉ khả dụng thông qua SQLCLR. Dưới đây cho thấy một ví dụ về việc thay thế một số ký tự "đặc biệt", nhưng để lại tất cả các chữ cái hợp lệ trong ít nhất một ngôn ngữ:
DECLARE @Test NVARCHAR(500);
SET @Test = N'this$is%a<>TEST,;to}⌡↕strip╞╟╚══¶out_ç_ƒ▀ special-ij-೫-chars-舛-დ-א-B';
SELECT SQL#.RegEx_Replace4k(@Test, N'[\W\p{Pc}-[,]]', N' ', -1, 1, NULL);
Trả về:
this is a TEST, to strip out ç ƒ special ij ೫ chars 舛 დ א B
Biểu thức RegEx có nghĩa là:
\W
= một RegEx "thoát" có nghĩa là "bất kỳ ký tự không phải từ "
\p{Pc}
= một "danh mục" Unicode của "Dấu câu, Trình kết nối" (điều này chỉ cần thiết cho trận đấu vì "danh mục" này được loại trừ đặc biệt bởi \W
lối thoát)
-[,]
= phép trừ lớp (điều này là cần thiết để loại trừ dấu phẩy khỏi khớp là "đặc biệt" vì chúng được bao gồm trong \W
lối thoát)
Bạn có thể thực hiện cập nhật bảng chỉ bằng cách phát hành:
UPDATE tbl
SET tbl.field = SQL#.RegEx_Replace4k(tbl.field, N'[\W\p{Pc}-[,]]', N' ', -1, 1, NULL)
FROM tbl
WHERE SQL#.RegEx_IsMatch4k(tbl.field, N'[\W\p{Pc}-[,]]', 1, NULL) = 1;
Xin lưu ý rằng đối với các ví dụ này, tôi đã sử dụng hai hàm có sẵn trong thư viện SQL #R phiên bản miễn phí của các hàm SQLCLR do tôi tạo (nhưng một lần nữa, chúng đều miễn phí). Cũng lưu ý rằng tôi đã sử dụng các phiên bản "4k" nhanh hơn do sử dụng NVARCHAR(4000)
thay vì các NVARCHAR(MAX)
loại tham số. Nếu dữ liệu của bạn đang sử dụng NVARCHAR(MAX)
, thì chỉ cần xóa "4k" khỏi tên hàm.
Xin vui lòng xem: