PL SQL和Java-创建动态查询
我有一个难题,我正在使用Java和Oracle,并试图将查询保留在PL / SQL方面。一切都很好,直到我有这些复杂的查询,其中可能有条件,也可能没有条件。
在Java中将WHERE
子句与条件放在一起并不难,但这并不好。
在PL / SQL方面,我还发现,"动态查询"的唯一可能性是字符串操作,例如
IF inputname IS NOT NULL THEN query := query ||' and NAME=' || inputname; END IF;
现在我在想,我要在PL / SQL中保留查询,并发送带有函数参数的" WHERE"子句。
有什么好的建议或者例子吗?
解决方案
从Java方面来看,SQLBuilder对我们可能有用。它允许我们编写经过编译时检查的Java代码,以动态生成sql:
String selectQuery = (new SelectQuery()) .addColumns(t1Col1, t1Col2, t2Col1) .addJoin(SelectQuery.JoinType.INNER_JOIN, joinOfT1AndT2) .addOrderings(t1Col1) .validate().toString();
在PL / SQL中使用:
EXECUTE IMMEDIATE lString;
这使我们可以将lString(VARCHAR2)构建到要使用的大多数SQL位中。例如
EXECUTE IMMEDIATE 'SELECT value FROM TABLE WHERE '||pWhereClause INTO lValue;
我们还可以返回多行并在EXECUTE IMMEDIATE中执行DDL语句。
正如我们所发现的那样,PL / SQL对于创建动态SQL并不令人满意,它的字符串操作很痛苦。我们可以从客户端发送where子句,但必须确保检查SQL注入,即确保短语以" where"开头,没有分号或者仅在末尾(如果它可能出现在中间)我们需要从字符串定界符中查找,只允许在其中输入),等等。另一种选择是存储过程,该过程采用字段过滤器的预定义参数列表,对参数字段的每一列应用" like"。
是的,立即执行也是我的朋友。感谢建议。我认为这一次我尝试仅发送带参数的WHERE子句
我认为将查询创建的整个逻辑放在一个地方(Java或者Oracle)会更好。我假设我们知道如何用Java做到这一点。在Oracle中,如果查询仅检索一行,则可以使用EXECUTE IMMEDIATE ... INTO子句。
如果查询返回多行并且具有单个参数(不使用IN运算符),则可以使用REF CURSOR策略来循环查询结果或者将游标本身返回到Java程序(如果使用,则必须导入Oracle Java语法) 。 Google中的第一个Ref Cursor答案
如果必须使用IN参数(或者在其他极少数情况下),则必须使用DBMS_SQL程序包解析查询,该程序包过于冗长且使用起来有些棘手,但非常灵活。 DBMS_SQL文档(在阅读方法之前观看流程图)