如何在弹簧数据存储库本机库中使用Oracle NVL函数



我试图在弹簧数据存储库的本机标语中使用Oracle'NVL函数。

当我在programId参数中传递null值时,它正在抛出异常(ORA-00932: inconsistent datatypes: expected NUMBER got BINARY),如果我在" ProgramID"中传递了有效的值,则它可以正常工作。

public interface ProgramRulesRepository
{
  public static final String FIND_PROGRAM_RULES_BY_PARTICIPANT_ID_AND_ROLE_OR_PROGRAM = " SELECT DISTINCT pr.id , pr.program_id , prgm.display_name , pr.group_id , pr.type , pr.cmmo_key FROM  program prgm , program_rule pr , program_audience pa , participant_audience paa WHERE prgm.id = pa.program_id AND pr.program_id = pa.program_id AND pa.audience_id = paa.audience_id AND pr.type = :roleType  AND paa.participant_id = :participantId "
      + " AND pr.program_id = NVL ( :programId ,pr.program_id )";
  @Query( value = FIND_PROGRAM_RULES_BY_PARTICIPANT_ID_AND_ROLE_OR_PROGRAM, nativeQuery = true )
List<Object[]> findByParticipantIdAndRoleTypeOrProgramId( @Param( "participantId" ) Long participantId, @Param( "roleType" ) String roleType, @Param( "programId" ) Long programId );

}

例外:

Caused by: java.sql.SQLSyntaxErrorException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY

使用冬眠时避免使用NVL和合并。合并功能需要具有相同类型的所有参数。NVL正在使用隐式铸造,当有二进制或varbinary时效果不佳。这个二进制来自哪里?好吧,Hibernate将NULL值设置为二进制类型,而忽略了Java支持的实际数据类型。当您将记录级别设置为跟踪时,您可以在输出中看到:

binding parameter [1] as [VARBINARY] - [null]

因此,当其他类型的cocece或nvl函数是数字时,您将获得该错误ORA-00932。

解决此问题的一个很好的解决方案是:

" AND (:programId IS NULL OR pr.program_id = :programId)"

这样做,如果您的参数为null,则此句子将导致true并且不会丢弃寄存器,如果未null将与存储在其字段中的值进行比较。

我在MongoDB上遇到了这个问题。但是我可以通过使用Mongotemplate来解决这个问题,

 Query query = new Query();
 Criteria criteria = new Criteria();
 List<Criteria> orCriterias = new ArrayList<>();
 if( dto.getId() != null) {    
   orCriterias.add(Criteria.where("id").is(Integer.parseInt(dto.getId())));
 }
 ... so on for other fields
criteria.orOperator(orCriterias.toArray(new Criteria[orCriterias.size()]));
query.addCriteria(criteria);
List<StudentDTO> recordsList = mongoTemplate.find(query, StudentDTO.class, 
"student_collection");

最新更新