【问题标题】:Invalid characters using Oracle 12c and ojdbc7 / ojdbc8 driver使用 Oracle 12c 和 ojdbc7 / ojdbc8 驱动程序的无效字符
【发布时间】:2018-01-30 16:16:39
【问题描述】:

通过我们的 REST API 在 Oracle 12c 数据库中持久化数据后,在从数据库中选择数据时无法识别特殊字符(它们显示为奇怪的字符)。

可能是 Oracle 数据库配置吗?我将在此处添加所有数据:

  • Oracle 版本:12.1.0.2.0
  • Java 驱动程序版本:ojdbc7-12.1.0.1.jar(最新可用)
  • Java 版本:JDK 8u162(最新可用)
  • 应用服务器:WildFly 9.0.1

如果我们将驱动程序降级到 OJDBC 6 并且它适用于数据库中已经存在的某些字符。

我们还在 JBoss 类路径中添加了 orai18n.jar 驱动程序,但没有任何改变。

Oracle 数据库 NLS 配置

发布

使用 JSON 有效负载的非常简单的后期操作:

获取

插入数据库后,我们得到了数据,但我们看不到特殊字符:

更新:我添加了另一个类型为 NVARCHAR2 的列,得到了回复:

代码

我们用一个简单的 REST 服务类隔离了这个简单项目中的问题。我们认为 Hibernate 可能是原因,但我们实现了一个纯 JDBC API,并且得到了相同的结果。

@Path("/parameter")
@Stateless
public class ParameterResource {

    @PersistenceContext
    private EntityManager em;

    @POST
    public void post(Parameter p) throws Exception {
        System.out.println("Value on POST: " + p.getValue());
        em.persist(p);
    }

    @GET
    @Path("/{id}")
    public Parameter get(@PathParam("id") String id) throws Exception {
        Parameter p = em.find(Parameter.class, id);
        System.out.println("Value on GET: " + p.getValue());
        return p;
    }

}

表 DDL 如下:

Name   Null?    Type
------ -------- -------------- 
ID     NOT NULL VARCHAR2(20)   
VALUE           VARCHAR2(200)  
VALUEN          NVARCHAR2(200) 

控制台输出如下,因此 REST API 应该没有问题,因为数据似乎在数据库接口处“损坏”了:

甚至添加了一个过滤器来确保我们在 Web 服务之间来回使用正确的编码。

@WebFilter("myFilter")
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }

}

SQL 开发人员

使用 SQL Developer 时也会出现该问题,该程序恰好在 Java 上运行并使用 OJDBC 8 驱动程序进行连接。

【问题讨论】:

  • 您的表使用的是VARCHAR2 还是NVARCHAR2? --- 您是否尝试调试代码以查看 Java 代码是否看到正确的字符,即确定是客户端 Java 还是导致问题的 Java 数据库?
  • @Andreas 我已将NVARCHAR 添加到测试中,请检查我的问题更新,它仍然给出奇怪的字符。是的,我已经检查过了,问题发生在“Java 数据库”中。
  • 1) 最新的 Java 驱动程序版本是 12.2.0.1,如果要匹配服务器版本,则为 12.1.0.2。请参阅oracle.com/technetwork/database/features/jdbc/index-091264.html --- 2) 您是否尝试过指定defaultNChar 属性?见docs.oracle.com/cd/E18283_01/java.112/e16548/…
  • @Andreas 1) 同样的问题 2) 它适用于NVARCHAR2 字段,但不适用于VARCHAR2。这是一个遗留数据库,我们无法更改字段类型,为什么它不适用于VARCHAR2?我应该打开 Oracle 票证吗?
  • 我很惊讶它曾经奏效过。您的字符集是 US7ASCII,表示 7 位 ASCII,没有 任何 重音字符。

标签: java oracle character-encoding ojdbc


【解决方案1】:

您的数据库是一个 US7ASCII 数据库。因此,您可以存储在 VARCHAR2 列中的唯一字符是 ASCII 字符。对于非 ASCII 字符,您必须使用 NVARCHAR2 列。我非常怀疑这是否适用于旧版本的 JDBC 驱动程序,或者您可能正在使用具有其他字符集(如 UTF8)的不同数据库。

【讨论】:

  • 现在看起来很明显。我们在运行 OJDBC6 测试时也犯了一个错误,所以你是对的。我们已经联系了 Oracle DBA,他打算将数据库编码更改为 8 位字符集。
猜你喜欢
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2020-10-15
相关资源
最近更新 更多