Spring 到 Oracle UTF-8 字符截断

Spring to Oracle UTF-8 character truncation

我遇到 Oracle 数据库中出现无效字符的问题。 “¿”或倒置的问号。我知道它是由 UTF8 编码被放入 Oracle 数据库的编码引起的。我期望的字符示例是“-”,它看起来像一个普通的连字符,但实际上不是,而“””应该是一个普通的单引号。

输入:“2020-08-31 – 2020-12-31”- 看起来像普通的连字符,但不是 输出:“2020-08-31 ¿2020-12-31”

我知道字符的主要来源是从办公程序(如 word)复制和粘贴,并将其转换为智能引号和其他内容。让用户关闭此功能不是一个可行的解决方案。

有一个很好的 article 处理这个问题,他们提供了一些解决方案:

因此使用的技术是 Eclipse、Spring、JDBC 4.2 版和 Oracle 12。

所以信息被输入到表单中,表单被保存,它从控制器传递到 DAO,当它在这里检查时,信息是正确的。当它从这里进入我看不见的 JDBC 时,一旦它进入数据库,我就无法判断它是否已经更改或者它是否发生在那里,但数据库存储了无效字符。

所以在插入语句到数据库之间的某处发生了这种情况。所以它要么是 JDBC 要么是数据库,但是如何判断以及如何修复?我已经更改了存储信息的字段,它最初是一个 varchar2,但我尝试了 nvarchar2,它仍然无效。

我知道这个 question 问的是同一主题,但答案对我没有帮助。

SELECT * FROM V$NLS_PARAMETERS WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');

PARAMETER                                                        VALUE                                                                CON_ID
---------------------------------------------------------------- ---------------------------------------------------------------- ----------
NLS_CHARACTERSET                                                 WE8ISO8859P15                                                             0 
NLS_NCHAR_CHARACTERSET                                           AL16UTF16                                                                 0 

所以在评论中我得到了 link 一些可能有用但它给我一个错误的东西。

@Override public Long createComment(Comment comment) {
        return jdbcTemplate.execute((Connection connection) -> {
            PreparedStatement ps = connection.prepareStatement("INSERT INTO COMMENTS (ID, CREATOR, CREATED, TEXT) VALUES (?,?,?,?)", new int[] { 1 });
            ps.setLong(1, comment.getFileNumber());
            ps.setString(2, comment.getCreator());
            ps.setTimestamp(3, Timestamp.from(comment.getCreated()));
            ((OraclePreparedStatement) ps).setFormOfUse(4, OraclePreparedStatement.FORM_NCHAR);
            ps.setString(4, comment.getText());
            if(ps.executeUpdate() != 1) return null;
            ResultSet rs = ps.getGeneratedKeys();
            return rs.next() ? rs.getLong(1) : null;
        });

An exception occurred: org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement cannot be cast to oracle.jdbc.OraclePreparedStatement

字符集 WE8ISO8859P15(resp. ISO 8859-15)不包含 ,因此您不能将它们存储在 VARCHAR2 数据字段中。

要么将数据库迁移到 Unicode(通常为 AL32UTF8),要么为该列使用 NVARCHAR2 数据类型。

我不熟悉 Java,但我猜你必须使用 getNString。链接文档应该提供一些解决问题的提示。