【问题标题】:Problems with CHAR columns in DB2 to Oracle 19C database migrationDB2 到 Oracle 19C 数据库迁移中的 CHAR 列问题
【发布时间】:2022-01-19 20:42:45
【问题描述】:

我正在开发一个在 JBOSS EAP 7 (JEE7) 应用服务器上运行的后端应用程序,该服务器的数据库将从 DB2 迁移到 Oracle 19c。具体来说,这个应用程序使用 Java 持久性框架(JPA 2.1,Hibernate 5.1.2)来访问数据库,我遇到了一个问题,当应用程序连接到 DB2 数据库时不会发生,而当应用程序是连接到 oracle 数据库。更具体地说,当主键字段的类型为 CHAR (9) 时,问题出在按主键的 SELECT 语句中。让我解释一下:要在 Oracle DB 的特定表中定位一条记录,其主键是 CHAR (9) 类型的列并且我试图定位的值有 8 个字母数字位置,我只在输入时检索记录第九位的空白字符。另一方面,当应用程序连接到 DB2 数据库时,不会出现这种情况。所以我想知道是否有其他人遇到过这个问题。另外,如果我使用 Oracle 客户端类型 SQLDeveloper 执行 SELECT,那么我所描述的这个问题就不会发生。最后,附上我正在使用的 JPA 实体的映射:

@Id
@Column(name = "POLISSA_SUBM", unique = true, nullable = false, length = 9)
public String getPolissaSubm() {
    return this.polissaSubm;
}

我还在 oracle DB 中添加了相关列的定义。

【问题讨论】:

  • 你能验证数据是导入的,最后有空格吗?还是只有 8 个字符长?
  • 不要使用CHAR,使用VARCHAR2
  • 我确认数据是以空格结尾的,我无法使用VARCHAR2数据类型。

标签: oracle hibernate java-ee-7 jpa-2.1


【解决方案1】:

这不是问题,而是在 Oracle 中使用 CHAR 数据类型时的预期行为。提到的问题在于使用CHAR 数据类型。

不要混淆,在 SQL Developer 中工作

对于这个例子...

create table polissa ( polissa_subm char(9));

insert into polissa values ('MY_KEY_8');

...两个查询都返回预期结果

select * from polissa where polissa_subm = 'MY_KEY_8';

POLISSA_S
---------
MY_KEY_8 

select * from polissa where polissa_subm = 'MY_KEY_8 ';

POLISSA_S
---------
MY_KEY_8 

这是由于Blank-Padded Comparison Semantics 所记录的

使用空格填充语义,如果两个值的长度不同,那么 Oracle 首先在较短的值的末尾添加空格,使它们的长度相等。

但是

仅当比较中的两个值都是数据类型 CHAR、NCHAR、文本文字的表达式或 USER 函数返回的值时,Oracle 才使用空白填充的比较语义。

不幸的是(实际上furtunatelly)Hibernate 使用绑定变量而不是文字,所以填充不会发生。

您甚至可以在 SQL Developer 中验证,简单运行

 select * from polissa where polissa_subm = :x;

并传递一个 8 字节长的字符串 - 你会注意到,你必须传递完整的填充的 9 字节字符串。

【讨论】:

    猜你喜欢
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 2021-01-05
    • 2020-10-17
    • 2014-08-24
    相关资源
    最近更新 更多