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,'@')(+)就报错,,

请各位高手帮忙解决,。。。如有解决必有其更多加分。。。

我觉得您的问题本身就有问题,可能是我没明白你的意思,我觉得你想要的结果是一下sql,不知道对不对?
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 个单独的连接?

如何在spring数据仓库nativeQuery中使用oracle NVL函数

如何能实现将oracle的查询结果排序后,只返回第一条记录

Oracle nvl函数

Oracle连接到SqlServer,如何实现呢?

如何使用 Oracle CTE 进行此类查询?