JPA - ORA-00920:无效的关系运算符

时间:2017-04-08 07:53:28

标签: java jpa oracle11g

我正在使用Spring JPA从Oracle DB中检索数据。我正在传递字符串参数

代码:

@Repository
public interface TbBamiTemplateRepository extends JpaRepository<TbBamiTemplate, TbBamiTemplatePK> {

    @Query(value = "SELECT * FROM TB_BAMI_TEMPLATES WHERE referral_queue=:referralQueue AND TXN_TYPE=:txnType AND REFERRAL_RSN=:reffralRsn AND (:wlClause OR (ROLE='ALL' AND (TEMPLATE_TYPE='PUSH' OR TEMPLATE_TYPE='MAIL') )) AND ACTION=:action",nativeQuery=true)
    List<TbBamiTemplate> findRecordTemplateDetails(@Param("referralQueue")String referralQueue, @Param("txnType")String txnType,@Param("reffralRsn")String reffralRsn,@Param("action")String action,@Param("wlClause")String wlClause);
}
//wlClause is :(ROLE = OPS AND TEMPLATE_TYPE =MAIL) OR (ROLE = RM1 AND TEMPLATE_TYPE =PUSH) OR (ROLE = RM AND TEMPLATE_TYPE =PUSH) OR (ROLE = ARM AND TEMPLATE_TYPE =PUSH)

我得到以下异常:

  org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
  ....
  ....

 Caused by: java.sql.SQLSyntaxErrorException: ORA-00920: invalid relational operator

1 个答案:

答案 0 :(得分:0)

从链接dba-oracle.com

  

ORA-00920无效的关系运营商
  原因:输入的搜索条件包含无效或缺少的关系运算符。

     

操作:包含有效的关系运算符,例如=,!=,^ =,&lt;&gt;,&gt;,   &lt;,&gt; =,&lt; =,ALL,ANY,[NOT] BETWEEN,EXISTS,[NOT] IN,IS [NOT] NULL,   或[NOT] LIKE在条件中。
如果输入搜索条件   连同缺少或无效的运算符,将抛出ORA-00920。   如果执行的SQL语句具有WHERE,也可以抛出ORA-00920   带有无效关系运算符的子句。

     

要更正ORA-00902,请使用有效的关系运算符,如:

=   !=    ^=  <>  >
< >=  <=  ALL ANY
[NOT] BETWEEN EXISTS  [NOT] IN    IS[NOT] NULL    [NOT] LIKE

如果仔细检查,您的查询语法会出错:

SELECT
   * 
FROM
   TB_BAMI_TEMPLATES 
WHERE
   referral_queue = :referralQueue 
   AND TXN_TYPE = :txnType 
   AND REFERRAL_RSN = :reffralRsn 
   AND 
   (
      :wlClause //what is this mean, i think something wrong is here ?

      OR 
      (
         ROLE = 'ALL' 
         AND 
         (
            TEMPLATE_TYPE = 'PUSH' 
            OR TEMPLATE_TYPE = 'MAIL'
         )
      )
   )
   AND ACTION = :action

应该是:

...

something = :wlClause 

OR 

...

修改

你不能像String一样传递一个查询!!

  ROLE = 'OPS' 
  AND TEMPLATE_TYPE = 'MAIL') 
  OR 
  (
     ROLE = 'RM1' 
     AND TEMPLATE_TYPE = 'PUSH'
  )
  OR 
  (
     ROLE = 'RM' 
     AND TEMPLATE_TYPE = 'PUSH'
  )
  OR 
  (
     ROLE = 'ARM' 
     AND TEMPLATE_TYPE = 'PUSH'
  )

因为当你尝试这样做时,这将在两个“查询”之间设置,而不是你想象的那样,所以避免这个问题,我建议改为NativeQuery,并用{{StringBuilder构建你的查询1}}例如:

String[] roles = {"OPS", "RM1", "RM", "ARM"};//list of roles
String[] template_type = {"MAIL", "PUSH", "PUSH", "PUSH"};//list of template_type

StringBuilder query = new StringBuilder();
query.append("SELECT * FROM TB_BAMI_TEMPLATES WHERE referral_queue = :referralQueue AND TXN_TYPE = :txnType "
        + "AND REFERRAL_RSN = :reffralRsn AND (");

String del = "";
for (int i = 0; i < roles.length; i++) {
    query.append("(ROLE = '").append(roles[i]).append("' AND TEMPLATE_TYPE = '").append(template_type[i]).append("')");
    del = "OR";
    query.append(del);
}
query.append("(ROLE = 'ALL' AND (TEMPLATE_TYPE = 'PUSH' OR TEMPLATE_TYPE = 'MAIL')))AND ACTION = :action");

System.out.println(query.toString());

//Create your query, and set parameters then get your results
Query q = em.createNativeQuery(query.toString());
q.setParametter("referralQueue", referralQueue);
q.setParametter("txnType", txnType);
q.setParametter("reffralRsn", reffralRsn);
q.setParametter("action", action);

List<Type> = q.getResulList();