我们的应用程序使用H2Sharp从C#(Framework v4)访问H2数据库。 H2Sharp继承DBDataAdapter并实现IDbDataAdapter。因此,我所问的最有可能适用于SqlDataAdapter,但我想澄清一下环境细节。
最近我们注意到在不同计算机上访问同一数据库时出现问题。我们观察到以下代码有时会起作用,有时会抛出错误:
DataRow row;
// Fill the row
String s = row["id"];
错误是“列ID不属于表Abcde”。
该应用程序可在运行Win7 64位的计算机上运行,Visual Studio 2010包含所有修补程序。复制到类似计算机的相同二进制文件和数据库会出现此错有趣的是,如果行改为
,代码就可以正常工作String s = row["ID"];
DataTable
将“CaseSensitive”属性设置为false
,因此我们最初无法弄清楚发生了什么。
事实证明,DataTable
具有“区域设置”属性,并且默认为已记录用户的区域设置(在Windows上“区域和语言”控制面板设置中的“格式”选项卡下设置) 7)。在它不起作用的机器上,用户区域设置被设置为土耳其语,我们看到“土耳其语问题”(*)的情况。
现在我了解问题的本质,我正在努力了解我必须解决的问题。我首先考虑是否有一种方法可以指定列名称等在不变文化中进行比较,但数据本身是在给定的语言环境中进行比较的。 H2 documentation并不是非常明确,但它的编写方式,听起来像整个数据库由一个主要设置控制。此外,SELECT * FROM INFORMATION_SCHEMA.COLLATIONS
不返回Unicode,因此似乎不可能使用此选项。
此外,DataTable documentation还建议将语言环境用于“用于表中的字符串比较”,因此似乎没有为列/表名称与用户数据指定不同行为的选项。 / p>
我发现this post提到了这个问题,并且接受的解决方案是在表/列名称中使用“I”字符而不是“i”。但是,我认为此解决方案假定代码在字符串比较之前执行ToUpper()而不是ToLower(),因此如果将来修改DataTable
代码,它可能会被破坏。
该帖子还有suggested solution个设置为UTF-8的SQL服务器设置。这似乎是一个更可行的解决方案。但是,我找不到为H2数据库执行此操作的方法(因为该设置似乎影响整个数据库并且没有UNICODE选项)。
我感谢任何输入/帮助/指导。
(*)土耳其语问题:土耳其语,ToUpper(i)==İ,ToLower(I)==(ı)
答案 0 :(得分:1)
我们继续使用表格/列名称中所有大写字母的suggested solution。即使这假设DataTable
后面的代码正在执行ToUpper()
而不是ToLower()
进行不区分大小写的比较,但此代码似乎不太可能改变其行为(这会破坏所有使用DataTable
进行不区分大小写的比较的代码。)
答案 1 :(得分:0)
异常是否有堆栈跟踪?你能发贴吗?
设置排序规则无济于事,因为排序规则只影响数据(列值)而不影响标识符。
对于标识符,H2使用toUpperCase(Locale.ENGLISH),因此它不受土耳其问题的影响(不再是;它曾经是一个问题,但是在几年前)。
我查看了H2Sharp源代码,但我没有发现问题(不使用ToUpper / ToLower)。我也没有在那里或在H2中找到错误消息“列......不属于表...”。