2009-04-30 69 views
5

Theo this, SQL Server 2K5 sử dụng UCS-2 nội bộ. Nó có thể lưu trữ dữ liệu UTF-16 trong UCS-2 (với các kiểu dữ liệu thích hợp, nchar, vv), tuy nhiên nếu có một ký tự bổ sung thì nó được lưu trữ dưới dạng 2 ký tự UCS-2.Lưu trữ dữ liệu UTF-16/Unicode trong SQL Server

Điều này mang lại các vấn đề rõ ràng với các hàm chuỗi, cụ thể là một ký tự được xử lý là 2 bởi SQL Server.

Tôi hơi ngạc nhiên khi SQL Server về cơ bản chỉ có thể xử lý UCS-2 và thậm chí nhiều hơn để điều này không được sửa trong SQL 2K8. Tôi đánh giá cao rằng một số trong những nhân vật này có thể không phải là tất cả những gì phổ biến.

Ngoài các chức năng được đề xuất trong bài viết, mọi đề xuất về cách tiếp cận tốt nhất để xử lý các hàm chuỗi (bị hỏng) và dữ liệu UTF-16 trong SQL Server 2K5.

+0

Chức năng chuỗi nào bị hỏng? – gbn

+3

LEN sẽ trả về số ký tự UCS-2 trong chuỗi, không phải số ký tự UTF-16. SUBSTRING sẽ phân tách các ký tự UTF-16 làm đôi. Tương tự cho LEFT và RIGHT. UPPER và LOWER cũng có thể sẽ phá vỡ. REVERSE chắc chắn sẽ phá vỡ. CHARINDEX và PATINDEX cũng có. Không chắc về DIFFERENCE và STUFF. Vì vậy, rất nhiều người trong số họ .... –

+2

Cảm ơn bạn đã chỉ ra điều này. Thực tế là nó không hỗ trợ TẤT CẢ các ký tự Unicode có nghĩa là một số giá trị chuỗi UTF-16 (ví dụ: từ Windows hoặc .NET) không hợp lệ để kết xuất vào SQL Server mà không cần xác minh. Để bất kỳ ứng dụng nào không có lỗi và kỹ thuật chính xác (cách các ký tự gây lỗi RARE không tạo ra chút khác biệt về độ chính xác), TẤT CẢ các chuỗi phải được xác thực để chứa các ký tự tương thích UCS-2 trước được lưu trữ trong SQL Server. Tuyệt vời! Cách làm cho công việc của tôi khó khăn hơn nhiều. – Triynko

Trả lời

2

Các hàm chuỗi hoạt động tốt với chuỗi ký tự unicode; những người quan tâm đến số ký tự xử lý ký tự 2 byte dưới dạng một ký tự đơn, không phải là hai ký tự. Những cái duy nhất để xem là len() và datalength(), trả về các giá trị khác nhau khi sử dụng unicode. Chúng trả về giá trị đúng của khóa học - len() trả về độ dài ký tự, và datalength() trả về độ dài theo byte. Họ chỉ xảy ra là khác nhau vì các ký tự hai byte.

Vì vậy, miễn là bạn sử dụng các chức năng thích hợp trong mã của mình, mọi thứ sẽ hoạt động một cách minh bạch.

EDIT: Chỉ cần kiểm tra lại Books Online, dữ liệu unicode đã làm việc seemlessly với chức năng chuỗi từ SQL Server 2000.

EDIT 2: Như đã chỉ ra trong các ý kiến, các chức năng chuỗi SQL Server không hỗ trợ bộ ký tự Unicode đầy đủ do thiếu hỗ trợ phân tích thay thế bên ngoài mặt phẳng 0 (hoặc nói cách khác, các hàm chuỗi của SQL Server chỉ nhận được tối đa 2 byte cho mỗi ký tự.) SQL Server sẽ lưu trữ và trả về dữ liệu chính xác, tuy nhiên bất kỳ hàm chuỗi dựa vào số ký tự sẽ không trả lại giá trị mong đợi. Cách phổ biến nhất để bỏ qua điều này có vẻ là xử lý chuỗi bên ngoài SQL Server, hoặc bằng cách sử dụng tích hợp CLR để thêm các hàm xử lý chuỗi nhận biết Unicode.

+5

Bạn đã hiểu sai câu hỏi. UTF-16 cho phép các ký tự bổ sung. Điều này hoạt động bằng cách lưu trữ một ký tự đơn (từ quan điểm của người dùng) trong 2 đơn vị mã, tức là 4 byte. UCS-2 không xử lý các ký tự bổ sung. Do đó 4 byte được coi là hai ký tự của SQL Server khi thực tế là một ký tự. –

+0

Chỉ dành cho các ký tự ngoài các ngôn ngữ được xác định chuẩn. Báo cáo chính sách này chủ yếu dành cho các ngôn ngữ lịch sử. – Rick

+0

Nhận xét về chỉnh sửa: Máy chủ SQL hoạt động tốt trên dữ liệu unicode UCS-2. UCS-2 là một tiêu chuẩn không được chấp nhận, các cửa sổ đã sử dụng UTF-16 trong nội bộ kể từ Win2K. –

-2

một cái gì đó để thêm, mà tôi chỉ học được cách cứng:

nếu bạn sử dụng một "n" lĩnh vực trong oracle (im chạy 9i), và truy cập nó thông qua oracleclient .net, dường như chỉ có tham số sql sẽ làm việc ... tiền tố unicode N'string 'doesnt dường như làm các trick nếu bạn có một số sql nội tuyến.

và bằng "công việc", ý tôi là: nó sẽ mất mọi ký tự không được bộ mã cơ sở hỗ trợ. Vì vậy, trong trường hợp của tôi, ký tự tiếng Anh hoạt động tốt, cyrillic biến thành dấu hỏi/rác.

đây là một cuộc thảo luận đầy đủ hơn về đề tài này: http://forums.oracle.com/forums/thread.jspa?threadID=376847

Wonder nếu biến ORA_NCHAR_LITERAL_REPLACE có thể được thiết lập trong chuỗi kết nối hoặc một cái gì đó.

+0

Hi boomhauer, câu hỏi là về Microsoft SQL Server. Câu trả lời của bạn có thể hữu ích ở một nơi khác. –

+0

wow ... có điều gì đó đã xảy ra ở đây. tôi đã đăng câu hỏi sai? Tôi gần như tự hỏi nếu SO screwed này lên, vì nó được khoảng từ feb 2010 ... –

+0

trong thực tế, tôi BIẾT câu trả lời này được sử dụng để được trên một câu hỏi! –

5

SQL Server 2012 hiện hỗ trợ UTF-16 bao gồm cặp thay thế. Xem http://msdn.microsoft.com/en-us/library/ms143726(v=sql.110).aspx, đặc biệt là phần "Ký tự bổ sung".

Vì vậy, một bản sửa lỗi cho vấn đề ban đầu là áp dụng SQL Server 2012.

+0

Mặc dù SQL Server 2012 giới thiệu các collations '_SC' có xử lý thích hợp các ký tự bổ sung, câu hỏi là _very_ cụ thể về liên quan đến SQL Server 2005. Ngoài ra, nó không phải là" cặp thay thế UTF-16 + "từ UTF-16 = "UCS-2 + cặp thay thế". –

Các vấn đề liên quan