2011-11-11 9 views
14

Tôi đang truy vấn cơ sở dữ liệu SQL Server sử dụng collation SQL_Latin1_General_CP850_BIN2. Một trong các hàng trong bảng có một varchar với một giá trị bao gồm ký tự +/- (mã thập phân 177 trong mã Windows-1252).Máy chủ SQL - Chuyển đổi varchar sang một đối chiếu khác (trang mã) để sửa mã hóa ký tự

Khi tôi truy vấn trực tiếp bảng trong SQL Server Management Studio, tôi nhận được một ký tự vô nghĩa thay vì ký tự +/- trong hàng này. Khi tôi sử dụng bảng này làm nguồn trong gói SSIS, bảng đích (sử dụng đối chiếu SQL_Latin1_General_CP1_CI_AS điển hình), kết thúc bằng ký tự +/- chính xác.

Bây giờ tôi phải xây dựng một cơ chế truy vấn trực tiếp bảng nguồn mà không có SSIS. Làm thế nào để tôi làm điều này theo cách mà tôi có được nhân vật chính xác thay vì vô nghĩa? Đoán của tôi là tôi sẽ cần phải chuyển đổi/đúc cột để collation SQL_Latin1_General_CP1_CI_AS nhưng điều đó không làm việc như tôi tiếp tục nhận được một ký tự vô nghĩa.

Tôi đã thử những điều sau đây không có may mắn:

select 
columnName collate SQL_Latin1_General_CP1_CI_AS 
from tableName 

select 
cast (columnName as varchar(100)) collate SQL_Latin1_General_CP1_CI_AS 
from tableName 

select 
convert (varchar, columnName) collate SQL_Latin1_General_CP1_CI_AS 
from tableName 

Tôi đang làm gì sai?

+1

Chào mừng bạn đến StackOverflow: nếu bạn gửi mẫu mã, XML hoặc dữ liệu, ** xin vui lòng ** làm nổi bật những dòng trong trình soạn thảo văn bản và bấm vào nút "mẫu mã" ('{}') trên thanh công cụ trình soạn thảo để định dạng và cú pháp độc đáo làm nổi bật nó! –

Trả lời

1

Chúng tôi có thể cần thêm thông tin. Đây là những gì tôi đã làm để tái sản xuất trên SQL Server 2008:

CREATE DATABASE [Test] ON PRIMARY 
    ( 
    NAME = N'Test' 
    , FILENAME = N'...Test.mdf' 
    , SIZE = 3072KB 
    , FILEGROWTH = 1024KB 
    ) 
    LOG ON 
    ( 
    NAME = N'Test_log' 
    , FILENAME = N'...Test_log.ldf' 
    , SIZE = 1024KB 
    , FILEGROWTH = 10% 
    ) 
    COLLATE SQL_Latin1_General_CP850_BIN2 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_PADDING ON 
GO 
CREATE TABLE [dbo].[MyTable] 
    (
    [SomeCol] [varchar](50) NULL 
    ) ON [PRIMARY] 
GO 
Insert MyTable(SomeCol) 
Select '±' Collate SQL_Latin1_General_CP1_CI_AS 
GO 
Select SomeCol, SomeCol Collate SQL_Latin1_General_CP1_CI_AS 
From MyTable 

Kết quả hiển thị ký tự gốc. Khai báo collation trong truy vấn sẽ trả về các ký tự thích hợp từ quan điểm của SQL Server tuy nhiên nó có thể là trường hợp mà các lớp trình bày sau đó chuyển đổi sang một cái gì đó nhưng khác nhau như UTF-8.

8

Chuyển đổi bộ ký tự được thực hiện ẩn hoàn toàn ở cấp kết nối cơ sở dữ liệu. Bạn có thể buộc chuyển đổi tự động tắt trong chuỗi kết nối ODBC hoặc ADODB với tham số "Tự động dịch = Sai". Điều này KHÔNG được khuyến khích. Xem: https://msdn.microsoft.com/en-us/library/ms130822.aspx

Đã xảy ra sự không tương thích với mã hóa trong SQL Server 2005 khi trang mã cơ sở dữ liệu và khách hàng không khớp. https://support.microsoft.com/kb/KbView/904803

Bảng điều khiển quản lý SQL 2008 trở lên là ứng dụng UNICODE. Tất cả các giá trị được nhập hoặc yêu cầu được hiểu như vậy ở cấp ứng dụng. Cuộc hội thoại đến và từ cột collation được thực hiện hoàn toàn. Bạn có thể xác minh điều này với:

SELECT CAST(N'±' as varbinary(10)) AS Result 

này sẽ trở lại 0xB100 đó là ký tự Unicode U + 00B1 (như đã nhập trong cửa sổ Management Console). Bạn không thể tắt "Tự động dịch" cho Management Studio.

Nếu bạn chỉ định một đối chiếu khác nhau trong lựa chọn, cuối cùng bạn sẽ kết thúc trong một chuyển đổi kép (có thể mất dữ liệu) miễn là "Tự động dịch" vẫn hoạt động. Ký tự ban đầu đầu tiên được chuyển đổi thành collation mới trong quá trình chọn, lần lượt được "Tự động dịch" sang mã "ứng dụng" thích hợp. Đó là lý do tại sao các thử nghiệm COLLATION khác nhau của bạn vẫn hiển thị tất cả cùng một kết quả.

Bạn có thể xác minh rằng quy định cụ thể đối chiếu KHÔNG có ảnh hưởng trong các lựa chọn, nếu bạn đúc kết quả như VARBINARY thay vì VARCHAR nên việc chuyển đổi SQL Server không mất hiệu lực của khách hàng trước khi nó được trình bày:

SELECT cast(columnName COLLATE SQL_Latin1_General_CP850_BIN2 as varbinary(10)) from tableName 
SELECT cast(columnName COLLATE SQL_Latin1_General_CP1_CI_AS as varbinary(10)) from tableName 

Điều này sẽ giúp bạn có được 0xF1 hoặc 0xB1 tương ứng nếu columnName chứa chỉ là nhân vật '±'

bạn vẫn có thể nhận được kết quả chính xác và chưa một ký tự sai, nếu font bạn đang sử dụng không cung cấp pr hoạt động glyph.

Vui lòng kiểm tra đại diện nội bộ thực tế của nhân vật của bạn bằng cách đúc các truy vấn để VARBINARY trên một mẫu thích hợp và xác minh xem mã này thực sự tương ứng với collation cơ sở dữ liệu định nghĩa SQL_Latin1_General_CP850_BIN2

SELECT CAST(columnName as varbinary(10)) from tableName 

Sự khác biệt về đối chiếu ứng dụng và cơ sở dữ liệu tăng gấp đôi collation có thể đi không được chú ý miễn là chuyển đổi luôn được thực hiện theo cùng một cách trong và ngoài. Rắc rối xuất hiện ngay sau khi bạn thêm một khách hàng với một đối chiếu khác nhau. Sau đó, bạn có thể thấy rằng chuyển đổi nội bộ không thể khớp chính xác với các ký tự.

Tất cả những gì đã nói, bạn nên nhớ rằng Management Studio thường không phải là tham chiếu cuối cùng khi diễn giải tập hợp kết quả. Ngay cả khi nó có vẻ vô nghĩa trong MS, nó vẫn có thể là đầu ra chính xác. Câu hỏi đặt ra là liệu các hồ sơ có hiển thị chính xác trong các ứng dụng của bạn hay không.

1

thử:

SELECT CAST(CAST([field] AS VARBINARY) AS varchar) 
+0

Điều này làm việc cho tôi. Bu tôi cũng cần phải thêm lập trình viên đó nên chỉ ra lenghts như (VARBINARY (120)) ... VARCHAR (120). Nếu nó không cắt giảm đầu ra. –

3

Phải được sử dụng chuyển đổi, không đúc:

SELECT 
CONVERT(varchar(50), N'æøåáäĺćçčéđńőöřůýţžš') 
COLLATE Cyrillic_General_CI_AI 

(http://blog.sqlpositive.com/2010/03/using-convert-with-collate-to-strip-accents-from-unicode-strings/)

+0

Trong khi điều này về lý thuyết có thể trả lời câu hỏi, [nó sẽ là thích hợp hơn] (// meta.stackoverflow.com/q/8259) để bao gồm các phần thiết yếu của câu trả lời ở đây, và cung cấp liên kết để tham khảo. – manetsus