3

我有一个现有的 SQL Server 2000 数据库,它将 UTF-8 表示的文本存储在 TEXT 列中。我没有修改列类型的选项,并且必须能够将来自 C# 程序的非 ASCII Unicode 数据存储到该列中。

这是代码:

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 Server 2000 已经过时了。你需要升级。

有什么建议么?

4

1 回答 1

7

如果您的数据库排序规则是 SQL_Latin1_General_CP1(美国版 SQL Server 2000 的默认值),那么您可以使用以下技巧将 Unicode 文本作为 UTF-8 存储在charvarchartext列中:

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_Latin1_General_CP1,那么您需要将 1252 替换为正确的代码页

注意:如果您查看企业管理器或查询分析器中存储的文本,您会看到奇怪的字符代替非 ASCII 文本,就像您在不支持 Unicode 的文本编辑器中打开 UTF-8 文档一样.

工作原理:在非 Unicode 列中存储 Unicode 文本时,SQL Server 自动将文本从 Unicode 转换为数据库排序规则指定的代码页。目标代码页中不存在的任何 Unicode 字符都将被不可逆转地损坏,这就是前两种方法不起作用的原因。

但是您使用方法一走在正确的轨道上。缺少的步骤是通过使用 Windows-1252 代码页将原始 UTF-8 字节转换为 Unicode 来“保护”原始 UTF-8 字节。现在,当 SQL Server 执行从 Unicode 到 Windows-1252 的自动转换时,它会恢复原样的原始 UTF-8 字节。

于 2013-04-13T03:21:59.840 回答