简体   繁体   English

DB2 到 Oracle 19C 数据库迁移中 CHAR 列的问题

[英]Problems with CHAR columns in DB2 to Oracle 19C database migration

I am working on a backend application that runs on the JBOSS EAP 7 (JEE7) application server whose database is to be migrated from DB2 to Oracle 19c.我正在开发一个在 JBOSS EAP 7 (JEE7) 应用服务器上运行的后端应用程序,该服务器的数据库将从 DB2 迁移到 Oracle。 Specifically, this application uses the Java persistence framework (JPA 2.1, Hibernate 5.1.2) to access the database and I am encountering a problem that does not occur when the application is connected to the DB2 database and it does occur when the application It is connected to the oracle DB. Specifically, this application uses the Java persistence framework (JPA 2.1, Hibernate 5.1.2) to access the database and I am encountering a problem that does not occur when the application is connected to the DB2 database and it does occur when the application It is连接到 oracle DB。 More specifically, the problem is in SELECT statements by primary key when the primary key field is of type CHAR (9).更具体地说,当主键字段的类型为 CHAR (9) 时,问题出在 SELECT 语句中。 Let me explain: To locate a record in a specific table of the Oracle DB whose primary key is a column of type CHAR (9) and the value I am trying to locate has 8 alphanumeric positions, I only retrieve the record if I enter a blank character in the ninth position.让我解释一下:要在 Oracle DB 的特定表中查找记录,该表的主键是 CHAR (9) 类型的列并且我要查找的值有 8 个字母数字位置,如果我输入一个第九个 position 中的空白字符。 On the other hand, this circumstance does not occur when the application is connected to the DB2 database.另一方面,当应用程序连接到 DB2 数据库时,不会出现这种情况。 So I am wondering if anyone else has had this problem.所以我想知道是否有其他人遇到过这个问题。 Also, say that this problem that I have described does not occur if I do the SELECT with an Oracle client type SQLDeveloper.另外,假设我使用 Oracle 客户端类型 SQLDeveloper 执行 SELECT,则不会发生我所描述的这个问题。 Finally, I attach the mapping of the JPA entity that I am using:最后,附上我正在使用的 JPA 实体的映射:

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

I also add the definition of the column in question in the oracle DB.我还在 oracle DB 中添加了相关列的定义。 在此处输入图像描述

This is not a problem , but expected behavior when using the CHAR data type in Oracle.这不是问题,而是在 Oracle 中使用CHAR数据类型时的预期行为。 The problem as mentioned is in using the CHAR datatype.提到的问题在于使用CHAR数据类型。

Do not be confused, that in SQL Developer is works不要混淆,在 SQL Developer中是有效

For this example...对于这个例子...

create table polissa ( polissa_subm char(9));

insert into polissa values ('MY_KEY_8');

... both queries return the expected result ...两个查询都返回预期结果

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 

This is due to Blank-Padded Comparison Semantics as documented这是由于记录的空白填充比较语义

With blank-padded semantics, if the two values have different lengths, then Oracle first adds blanks to the end of the shorter one so their lengths are equal.使用空白填充语义,如果两个值的长度不同,则 Oracle 首先将空白添加到较短的末尾,以便它们的长度相等。

but

Oracle uses blank-padded comparison semantics only when both values in the comparison are either expressions of data type CHAR, NCHAR, text literals, or values returned by the USER function. Oracle 仅当比较中的两个值都是数据类型 CHAR、NCHAR、文本文字的表达式或 USER function 返回的值时,才使用空白填充的比较语义。

Unfortunatelly (actually furtunatelly ) Hibernate uses bind variables and not literals , so the padding does not happen.不幸的是(实际上是furtunatelly ) Hibernate使用绑定变量而不是文字,因此不会发生填充。

You may verify is even in SQL Developer, simple run您甚至可以在 SQL Developer 中验证,简单运行

 select * from polissa where polissa_subm = :x;

and pass an 8 byte long string - you get noting, you must pass teh full padded 9 byte string.并传递一个 8 字节长的字符串 - 你会注意到,你必须传递完整的填充 9 字节字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM