Có một số điều cần lưu ý ở đây:
-
Nếu bạn muốn xem chính xác ký tự ở đó, bạn có thể chuyển đổi giá trị thành
VARBINARY
sẽ cung cấp cho bạn giá trị hex / nhị phân của tất cả các ký tự trong chuỗi và không có khái niệm về ký tự "ẩn" trong hex:DECLARE @PostalCode NVARCHAR(20); SET @PostalCode = N'053000'+ NCHAR(0x2008); -- 0x2008 = "Punctuation Space" SELECT @PostalCode AS [NVarCharValue], CONVERT(VARCHAR(20), @PostalCode) AS [VarCharValue], CONVERT(VARCHAR(20), RTRIM(@PostalCode)) AS [RTrimmedVarCharValue], CONVERT(VARBINARY(20), @PostalCode) AS [VarBinaryValue];
Lợi nhuận:
NVarCharValue VarCharValue RTrimmedVarCharValue VarBinaryValue 053000 053000? 053000? 0x3000350033003000300030000820
NVARCHAR
dữ liệu được lưu trữ dưới dạng UTF-16 hoạt động trong bộ 2 byte. Nhìn vào 4 chữ số hex cuối để xem bộ 2 byte ẩn là gì, ta thấy "0820". Vì Windows và SQL Server là UTF-16 Little Endian (tức là UTF-16LE), các byte có thứ tự ngược lại. Lật 2 byte cuối cùng -08
và20
- chúng tôi nhận được "2008", là "Dấu cách chấm câu" mà chúng tôi đã thêm quaNCHAR(0x2008)
.Ngoài ra, xin lưu ý rằng
RTRIM
không giúp được gì ở đây. -
Nói một cách đơn giản, bạn chỉ có thể thay thế dấu chấm hỏi bằng không:
SELECT REPLACE(CONVERT(VARCHAR(20), [PostalCode]), '?', '');
-
Quan trọng hơn, bạn nên chuyển đổi
[PostalCode]
trường thànhVARCHAR
để nó không lưu trữ các ký tự này. Không quốc gia nào sử dụng các chữ cái không được đại diện trong bộ ký tự ASCII và không hợp lệ cho kiểu dữ liệu VARCHAR, ít nhất là theo như tôi đã từng đọc (xem phần dưới cùng để tham khảo). Trên thực tế, những gì được phép là một tập hợp con khá nhỏ của ASCII, có nghĩa là bạn có thể dễ dàng lọc trên đường vào (hoặc chỉ làm tương tựREPLACE
như được hiển thị ở trên khi chèn hoặc cập nhật):ALTER TABLE [table] ALTER COLUMN [PostalCode] VARCHAR(20) [NOT]? NULL;
Đảm bảo kiểm tra
NULL
hiện tại /NOT NULL
cài đặt cho cột và làm cho nó giống như trong câu lệnh ALTER ở trên, nếu không nó có thể được thay đổi vì giá trị mặc định làNULL
nếu không được chỉ định. -
Nếu bạn không thể thay đổi giản đồ của bảng và cần thực hiện "làm sạch" dữ liệu xấu định kỳ, bạn có thể chạy như sau:
;WITH cte AS ( SELECT * FROM TableName WHERE [PostalCode] <> CONVERT(NVARCHAR(50), CONVERT(VARCHAR(50), [PostalCode])) ) UPDATE cte SET cte.[PostalCode] = REPLACE(CONVERT(VARCHAR(50), [PostalCode]), '?', '');
Xin lưu ý rằng truy vấn trên không hoạt động hiệu quả nếu bảng có hàng triệu hàng. Tại thời điểm đó, nó sẽ cần được xử lý trong các tập hợp nhỏ hơn thông qua một vòng lặp.
Để tham khảo, đây là bài viết trên wikipedia về Mã bưu chính , hiện tại nói rằng các ký tự duy nhất từng được sử dụng là:
Và về kích thước tối đa của trường, đây là Danh sách mã bưu chính của Wikipedia