2013-04-12 1 views
3

У меня есть существующая база данных SQL Server 2000, в которой хранятся представления текста UTF-8 в столбце TEXT. У меня нет возможности изменять тип столбца и он должен иметь возможность хранить данные Unicode без ASCII из программы C# в этот столбец.Как хранить байты UTF-8 из строки C# в столбце TEXT SQL Server 2000

Вот код:

sqlcmd.CommandText = 
    "INSERT INTO Notes " + 
    "(UserID, LocationID, Note) " + 
    "VALUES (" + 
     Note.UserId.ToString() + ", " + 
     Note.LocationID.ToString() + ", " + 
     "@note); " + 
    "SELECT CAST(SCOPE_IDENTITY() AS BIGINT) "; 

SqlParameter noteparam = new SqlParameter("@note", System.Data.SqlDbType.Text, int.MaxValue); 

На данный момент я попробовал несколько различных способов, чтобы получить мои UTF-8 в данных параметра. Например:

// METHOD ONE 
byte[] bytes = (byte[]) Encoding.UTF8.GetBytes(Note.Note); 
char[] characters = bytes.Select(b => (char) b).ToArray(); 
noteparam.Value = new String(characters); 

Я также попытался просто

// METHOD TWO 
noteparam.Value = Note.Note; 

И

// METHOD THREE 
byte[] bytes = (byte[]) Encoding.UTF8.GetBytes(Note.Note); 
noteparam.Value = bytes; 

продолжается, вот остальная часть кода:

sqlcmd.Parameters.Add(noteparam); 
sqlcmd.Prepare(); 

try 
    { 
    Note.RecordId = (Int64) sqlcmd.ExecuteScalar(); 
    } 
catch 
    { 
    return false; 
    } 

Метод один (получить байты UTF8 в строку) делает что-то странное - Я думаю, что UTF-8 кодирует строку второй раз.

Метод два магазина мусора.

Метод три вызывает исключение в ExecuteScalar(), утверждая, что он не может преобразовать параметр в строку.

Вещи, которые я уже знаю, так что не нужно говорить мне:

  • SQL Server 2000 является прошлое/приближающийся конец срока службы
  • TEXT столбцы не предназначены для текста Unicode
  • Серьезно, SQL Сервер 2000 старый. Вам нужно обновить.

Любые предложения?

+0

Возможный дубликат [Напишите utf-8 на сервер sql Текстовое поле, использующее ADO.Net и поддерживающее байты UTF-8] (http://stackoverflow.com/questions/2883308/write-utf-8-to- a-sql-server-text-field-using-ado-net-and-maintain-the-utf-8-byte) –

+0

Не дубликат. SQL Server 2000 не поддерживает VARCHAR (MAX), поэтому его решение не будет работать. – Craig

ответ

4

Если параметры сортировки базы данных SQL_Latin1_General_CP1 (по умолчанию для американской версии SQL Server 2000), то вы можете использовать следующий трюк, чтобы сохранить текст Unicode, как UTF-8 в char, varchar или text колонки:

byte[] bytes = Encoding.UTF8.GetBytes(Note.Note); 
noteparam.Value = Encoding.GetEncoding(1252).GetString(bytes); 

Позже, когда вы хотите прочитать обратно текст, обратный процесс:

SqlDataReader reader; 
// ... 
byte[] bytes = Encoding.GetEncoding(1252).GetBytes((string)reader["Note"]); 
string note = Encoding.UTF8.GetString(bytes); 

Если параметры сортировки базы данных не SQL_Lat in1_General_CP1, тогда вам нужно будет заменить 1252 правильным code page.

Примечание: Если вы посмотрите на хранящийся тексте в Enterprise Manager или Query Analyzer, вы увидите странные символы вместо не-ASCII текст, так же, как если бы вы открыли документ в кодировке UTF-8 в текстовом редакторе который не поддерживает Unicode.

Как это работает: При сохранении текста в Unicode в столбце, отличном от Юникода, SQL Server автоматически преобразует текст из Юникода на кодовую страницу, заданную путем сортировки базы данных.Любые символы Юникода, которые не существуют на целевой кодовой странице, будут необратимо искажены, поэтому ваши первые два метода не работают.

Но вы были на правильном пути с методом один. Отсутствующий шаг - «защитить» необработанные байты UTF-8 путем преобразования их в Unicode с помощью кодовой страницы Windows-1252. Теперь, когда SQL Server выполняет автоматическое преобразование из Unicode в Windows-1252, он возвращает неиспользуемые исходные байты UTF-8.

+0

Это именно то, что мне нужно. Я искал кодировку, которая просто оставила значения каждого байта/символа. Не удалось найти какую-либо документацию по любому из кодировок или как они работают. Спасибо за вашу помощь. – Craig