Oracle踩坑:java.sql.SQLSyntaxErrorException: ORA-01788: 此查询块中要求 CONNECT BY 子句
1.建表时列名避免关键字
1.1.错误回顾
在service层我正常的调用mybatisplus进行插入/更新操作
mainDepart.setId(id)
.setCode(code)
.setName(name)
.setlevel(level)
.setParentId(parentCodeCode)
.setStatus(status);
try {
mainDepart.setSort(Integer.valueOf(sort));
}catch (NumberFormatException e){
log.warn("sort的值为\"{}\",不是正确的数字类型",sort);
}
mainDepartService.saveOrUpdate(mainDepart);
控制台报了以下错误
==> Preparing: SELECT id,parent_id,name,related,code,level,level_name,sort,create_time,update_time,status FROM MBD_MAIN_DEPART WHERE id=?
==> Parameters: 100001(String)
2024-04-30 14:46:46.695 [http-nio-8080-exec-9] ERROR druid.sql.Statement:149 - {conn-10005, pstmt-20015} execute error. SELECT id,parent_id,name,related,code,level,level_name,sort,create_time,update_time,status FROM MBD_MAIN_DEPART WHERE id=?
java.sql.SQLSyntaxErrorException: ORA-01788: 此查询块中要求 CONNECT BY 子句
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
1.2.错误原因
CONNECT BY
关键字是在级联查询时才会用到,为什么这个简单的插入/更新操作需要用到级联查询?
原来是我的数据库设置了一列名为level
。在Oracle中,LEVEL
是一个伪列,它在层次查询中使用,通常是与CONNECT BY
子句一起使用的。在查询时需要对列名添加双引号才能正常查询
SELECT id,parent_id,name,related,code,"LEVEL",level_name,sort,create_time,update_time,status FROM MBD_MAIN_DEPART WHERE id='11'
而MyBatisPlus在此处查询时,并没有对level
字段添加双引号,导致查询到伪列level
,从而导致了这个错误
1.3.避免
Oracle中的伪列是一种特殊类型的列,它们不是物理存储在表中的,而是由数据库在执行查询时动态生成的。当你在创建表或向表中插入数据时,需要注意这些伪列的名称,以避免与它们冲突。Oracle中的一些常见伪列包括:
ROWID
: 每一行的物理地址。ROWNUM
: 查询结果集的行号,它表示行出现的顺序。SYS_DATE
: 当前系统的日期和时间。LEVEL
: 在使用START WITH ... CONNECT BY
层次查询时返回层次结构中节点的级别。ORACLE_ROWSCN
: 数据行的SCN(系统改变号)或表的SCN。CURRVAL
: 序列的当前值(在NEXTVAL
被引用后)。NEXTVAL
: 序列的下一个值。