为什么Sql CE会改变我的unicode值?

时间:2011-02-15 22:31:24

标签: c# sql-server-ce

我正在从各种来源提取各种文档的非结构化文本。我正在使用Sql Server Compact Edition 3.5。

我正在创建一个包含唯一单词的查找表,并通过ID作为标识列引用它们。我发现问题似乎是unicode。

在插入术语“定义”时,我正在针对已经具有“定义”的行遇到唯一键约束。如果你仔细检查这两个,你会发现我插入的值,不是'f'和'i',而实际上是一个字符。然而,SqlCe正试图将其转换为存在和'f'以及'i'。一个单词中有十个字符,另一个单词中有十一个字符,但SqlCe认为它们是相同的。

表格列是nvarchar。

我将参数指定为nvarchar。

查询非常简单:

            cmd.CommandText = "INSERT INTO dictionary(lemma) VALUES(?);";

            DbParameter lemma = cmd.CreateParameter();
            cmd.Parameters.Add(lemma);

            for (int i = 0; i < terms.Count; i++)
            {
                lemma.Value = terms[i].Key;
                cmd.ExecuteNonQuery();
            }

我也试过了:

            cmd.CommandText = "INSERT INTO dictionary(lemma) VALUES(?);";

            SqlCeParameter lemma = new SqlCeParameter("lemma", SqlDbType.NVarChar);
            cmd.Parameters.Add(lemma);

            for (int i = 0; i < terms.Count; i++)
            {
                lemma.Value = terms[i].Key;
                cmd.ExecuteNonQuery();
            }

在我插入的内容中,'fi'字符的字节数为1 251,而不是'f'和'i'105 0,110 0。 请参阅以下内容:

 {byte[20]}
 [0]: 100
 [1]: 0
 [2]: 101
 [3]: 0
 [4]: 1
 [5]: 251
 [6]: 110
 [7]: 0
 [8]: 105
 [9]: 0
 [10]: 116
 [11]: 0
 [12]: 105
 [13]: 0
 [14]: 111
 [15]: 0
 [16]: 110
 [17]: 0
 [18]: 115
 [19]: 0

而数据库中的值(一个SqlCe被视为违反唯一键)是:

{byte[22]}
[0]: 100
[1]: 0
[2]: 101
[3]: 0
[4]: 102
[5]: 0
[6]: 105
[7]: 0
[8]: 110
[9]: 0
[10]: 105
[11]: 0
[12]: 116
[13]: 0
[14]: 105
[15]: 0
[16]: 111
[17]: 0
[18]: 110
[19]: 0
[20]: 115
[21]: 0

如何让SQL Server CE正确插入值?

编辑:更正了上面显示的代码。

2 个答案:

答案 0 :(得分:2)

SQL CE不会改变您的任何值。问题是您已将列定义为IDENTITY,它仅允许唯一值,SQL CE通过使用归类规则确定VARCHARS的唯一性。默认情况下是匹配具有文化意识的字符串,因此'fi'='fi','Å'='Å'等等。

我不知道任何将每个Unicode值比较为不同的SQL排序规则。如果这确实是您想要的,则必须将数据存储为VarBinary并执行二进制比较。

重新考虑将字符比较为二进制的愿望,SQL将VarChar定义为人类可读的文本,SQL和Unicode都指定相应的连字,变音符号等。作为匹配字符串。这是有道理的,人们真的读它们是相同的,并且在大多数字体中都无法区分。

答案 1 :(得分:0)

尝试

for (int i = 0; i < terms.Count; i++)
{
    cmd.CommandText = "INSERT INTO dictionary (lemma) VALUES (@lemma)";
    cmd.parameters.AddWithValue(@lemma, lemma);         
    cmd.ExecuteNonQuery();
}