【问题标题】:Oracle, utf-8, NVARCHAR2, and a lot of confusionoracle, utf-8, NVARCHAR2,还有很多混乱
【发布时间】:2011-06-06 21:42:55
【问题描述】:

我在 oracle 10g 数据库中有以下“翻译”表:

ID  VARCHAR2(100 BYTE)
LANGUAGE    CHAR(2 BYTE)
COUNTRY CHAR(2 BYTE)
TRANSLATION NVARCHAR2(2000 CHAR)
TRACK_TIMESTAMP DATE
TRACK_USER  VARCHAR2(2000 BYTE)

当我尝试这样做时:

update translation set translation = 'œ' where id = 'MY_ID' And language = 'fr';

然后我运行这个:

select * from translation where id = 'MY_ID' and language = 'fr';

翻译栏显示:S 而不是œ,我不知道为什么。

由于遗留问题,我无法将整个数据库转换为使用 UTF-8,还有其他选择吗?

当前国家字符集是 AL16UTF16。普通字符集是WE8ISO8859P1。

我目前使用的是 java 1.6

以上是一个简化的例子。这是查询在我的实际应用程序中的样子:

UPDATE TRANSLATION SET TRANSLATION=? WHERE TRANSLATION.COUNTRY=? and TRANSLATION.ID=? and TRANSLATION.LANGUAGE=? 1=1,800 - 2,500 œufs par heure 2=CA 3=3_XT_FE_ECS18 4=fr

这里的问题不是添加œufs,而是添加¿ufs

【问题讨论】:

  • 数据库的国家字符集是什么?您真的在生成使用硬编码字符串文字的 UPDATE 语句吗?还是您使用绑定变量?如果您使用绑定变量,应用程序是否将传入的数据的数据类型识别为 NVARCHAR2 而不仅仅是 VARCHAR2?
  • AL16UTF16。普通字符集是 WE8ISO8859P1。不,我不会生成使用硬编码字符串文字的更新语句。我试图尽可能地简化这个例子。我们目前使用 s2j,我也尝试使用 springs jdbcTemplate 并得到:'¿ufs'。我不确定 s2j 是否将其识别为 nvarchar2,但它将其返回类型从字符串更改为对象,因此我认为它不会将其视为 varchar2。感谢您的帮助,如果我缺少任何其他信息,请告诉我。

标签: oracle spring utf-8 nvarchar


【解决方案1】:

由于您使用的是绑定变量而不是硬编码文字,因此您应该能够将 Unicode 字符串传递给您的 UPDATE 语句。

如果您使用直接 JDBC 写入数据库,则在 JDBC 开发人员指南中的 writing data to a NVARCHAR2 column 中有一个示例。如果您使用的是 1.5 JVM,则必须对每个 NVARCHAR2 列使用 OraclePreparedStatement.setFormOfUse 调用。在 1.6 JVM 中,由于 JDBC 4.0 添加了 NCHAR 和 NVARCHAR2 类型,生活变得更加轻松。如果您使用的是 1.5 JVM,那么获得像 Spring 这样的 ORM 框架来使用 Oracle 对 JDBC 的扩展可能不是一件容易的事。我对 Spring 不够熟悉,不知道需要哪些步骤才能实现。

您可能能够修改连接字符串以指定 defaultNChar=true。这将强制驱动程序使用国家字符集处理所有字符列。这可能足以解决您的问题,而无需让 Spring 使用 OraclePreparedStatement 扩展。

【讨论】:

  • 感谢您的回复。我在原始帖子中添加了其他信息。阅读您的帖子后,我一直在研究 s2j,我认为问题在于我使用的是 ojdbc14.jar,我将获得最新的结果并发表评论。再次感谢您提供的信息!
  • 好的,现在我再次感到困惑,我更新到 ojdbc6.jar 并且当我查看元数据时,nvarchar2 列仍然返回类型 1111(java.sql.Types 中的 OTHER)虽然我认为它应该映射到 -9(在 java.sql.Types 类中找到的 NVARCHAR 变量)。我在这里错过了什么吗?
  • 你使用的是什么版本的JVM?您发出什么请求以返回元数据?你在使用 ResultSetMetaData 类吗?还是别的什么?
  • 1. JVM 1.6。 2.调用java.sql.DatabaseMetaData检索:java.sql.Connection getMetaData()。 3. 不,我应该是吗? 4. 是的,java.sql.DatabaseMetaData。
  • 那么使用DatabaseMetaData还可以吗?它给了我 NVARCHAR2 列的 1111 类型。它不应该给我-9吗?
猜你喜欢
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 2011-05-23
相关资源
最近更新 更多