我正在使用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
答案 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
...
修改强>
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();