我试图在弹簧数据存储库的本机标语中使用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");