我的UI页面有一个包含3个字段的搜索表单,用户应该可以在任何给定的组合中搜索一个/所有3个表单。我试图想出一个适用于所有这些场景的SQL,而不是动态生成它。
在Oracle中,我曾经做过类似下面的事情:
select * from USER_TABLE where (firstname is null OR firstname = :p_first ) AND
(:p_last is null OR lastname = :p_last ) AND (:p_deptid is null OR deptid= :p_deptid )
我想在zOS上的DB2上做同样的事情。这是我到目前为止最接近它的工作。
select * from USER_TABLE where (COALESCE(:firstname, 'x') = 'x' OR firstname = :p_first ) AND
(COALESCE(:p_last, 'x') = 'x' OR lastname = :p_last) AND (COALESCE(:p_deptid, 'x') = 'x' OR deptid= :p_deptid )
p_first,p_last和p_deptid是具有用户输入值的参数。
最终,我希望能够在JPA中将此查询用作NamedQuery。
更新:(根据要求更新了更多详细信息)
我几乎没有理由对Oracle的查询版本进行略微修改。
1)@Turophile - 当我使用完全相同的SQL (:p_first为null或firstname =:p_first)时,我收到以下错误:
[Error Code: -417, SQL State: 42609] A STATEMENT STRING TO BE PREPARED INCLUDES PARAMETER MARKERS AS THE OPERANDS OF THE SAME OPERATOR. SQLCODE=-417, SQLSTATE=42609, DRIVER=4.18.60. 2) [Error Code: -516, SQL State: 26501] THE DESCRIBE STATEMENT DOES NOT SPECIFY A PREPARED STATEMENT. SQLCODE=-516, SQLSTATE=26501, DRIVER=4.18.60. 3) [Error Code: -514, SQL State: 26501] THE CURSOR SQL_CURLH200C1 IS NOT IN A PREPARED STATE. SQLCODE=-514, SQLSTATE=26501, DRIVER=4.18.60
2)所以,我想出了' COALESCE'它的版本。我提供的SQL并没有真正起作用。看起来DB2期望&COFFESCE'中的两个操作数的字符串长度。等于或大于。也就是说,如果我期望:p_deptid的长度为5,则第二个操作数必须等于或大于5.因此,我需要填充上述SQL中的' x' s。
select * from USER_TABLE where (COALESCE(:firstname, 'x') = 'x' OR firstname = :p_first ) AND
(COALESCE(:p_last, 'x') = 'x' OR lastname = :p_last) AND (COALESCE(:p_deptid, 'xxxxxx') = 'xxxxxx' OR deptid= :p_deptid )
否则,我收到此错误:
[Error Code: -302, SQL State: 22001] THE VALUE OF INPUT VARIABLE OR PARAMETER NUMBER 1 IS INVALID OR TOO LARGE FOR THE TARGET COLUMN OR THE TARGET VALUE. SQLCODE=-302, SQLSTATE=22001, DRIVER=4.18.60
我是DB2的新手,基于我的发现,语法似乎与Oracle非常相似,但它看起来行为略有不同。如果在DB2世界中有更好的方法,我也愿意接受建议。