ORACLE 右连接又加NVL,如何实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORACLE 右连接又加NVL,如何实现相关的知识,希望对你有一定的参考价值。
SELECT T.CO,T.EVEBXINSHPQTY,....,T.PRCUN,T2.TXEMP FROM TXD000GHFA1 T ,T08040DAC21 T2
WHERE T.CO = T2.CO(+) AND T.DTLVDP = T2.DTLVDP(+) AND T.PDNO = T2.PDNO(+)
AND NVL(T.PDURCLASSID,'@') = NVL(T2.PDURCLASSID,'@')(+) AND NVL(T.SPEC,'@') = NVL(T2.SPEC,'@')(+)
我的两个TABLET,T2想通过5个栏位相连接,因为T2资料不全时,也要查出T1的资料,所以用到右连接。但因为后面的两个栏位是可以为NULL的,所以要加NVA()处理,这样之后,NVL(T2.PDURCLASSID,'@')(+) AND NVL(T.SPEC,'@') = NVL(T2.SPEC,'@')(+)就报错,,
请各位高手帮忙解决,。。。如有解决必有其更多加分。。。
create table table1 as (SELECT T.CO a1,T.DTLVDP a2,T.PDNO a3,nvl(T.PDURCLASSID,\'@\') a4,nvl(T.SPEC,\'@\') a5 FROM TXD000GHFA1 T ,T08040DAC21 T2
WHERE T.CO = T2.CO(+) AND T.DTLVDP = T2.DTLVDP(+) AND T.PDNO = T2.PDNO(+) ) );
create table table1 as (SELECT T2.CO a1,T2.DTLVDP a2,T2.PDNO a3,nvl(T2.PDURCLASSID,\'@\') a4,nvl(T2.SPEC,\'@\') a5 FROM TXD000GHFA1 T ,T08040DAC21 T2
WHERE T.CO = T2.CO(+) AND T.DTLVDP = T2.DTLVDP(+) AND T.PDNO = T2.PDNO(+) ) );
select * from table1 a,table2 b where a.a4=b.a4(+) and a.a5=b.a5(+);
不知道您要的是不是这个结果,上面的也可以建成VIEW,可能更好些,如果要写成一句SQL的话,比较困难,本人也不推荐使用。 参考技术A (NVL(T2.PDURCLASSID, '@'))(+) 再加个括号试试呢
如何在spring数据仓库nativeQuery中使用oracle NVL函数
【中文标题】如何在spring数据仓库nativeQuery中使用oracle NVL函数【英文标题】:How to use oracle NVL function in spring data repository nativeQuery 【发布时间】:2017-11-06 15:56:53 【问题描述】:我正在尝试在 Spring Data Repository 的 nativeQuery 中使用 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
【问题讨论】:
Spring Data - ignore parameter if it has a null value的可能重复 【参考方案1】:我在使用 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");
【讨论】:
我通过应用条件忽略空参数并将条件添加到条件列表。然后将“orOperators”、“andOperators”等运算符应用为文档docs.spring.io/spring-data/mongodb/docs/2.0.8.RELEASE/reference/…。然后将该条件列表添加到 Query。 这个东西也在spring jira“jira.spring.io/browse/DATAJPA-209”中讨论。请也参考它以获得想法。【参考方案2】:在使用 Hibernate 时避免使用 NVL 和 COALESCE。 COALESCE 函数需要具有相同类型的所有参数。 NVL 使用隐式转换,当存在 BINARY 或 VARBINARY 时效果不佳。这个 BINARY 是从哪里来的?好吧,Hibernate 将 NULL 值设置为 BINARY 类型并忽略 Java 支持的真实数据类型。当您将日志记录级别设置为跟踪时,您可以在输出中看到:
binding parameter [1] as [VARBINARY] - [null]
因此,当 COALESCE 或 NVL 函数中的其他类型为例如 NUMBER 时,您将收到错误 ORA-00932。
【讨论】:
【参考方案3】:这个问题的一个很好的解决方案是:
" AND (:programId IS NULL OR pr.program_id = :programId)"
这样做,如果你的参数为空,这句话将返回TRUE,不会丢弃寄存器,如果不为空,将与存储在其字段中的值进行比较。
【讨论】:
以上是关于ORACLE 右连接又加NVL,如何实现的主要内容,如果未能解决你的问题,请参考以下文章
oracle中的右连接和左连接有啥区别?如果我们可以实现左连接在右连接中可以做的事情,为啥要使用 2 个单独的连接?