我陷入两难境地,我正在使用Java和Oracle并尝试在PL / SQL端保持查询。一切都很好,直到我有这些复杂的查询,可能有条件,也可能没有条件。
将WHERE
子句与条件放在一起并不难,但这并不好。
在PL / SQL方面,我还发现dynamic queries
的唯一可能性是字符串操作,如
IF inputname IS NOT NULL THEN
query := query ||' and NAME=' || inputname;
END IF;
现在我在想,我将在PL / SQL中离开查询并使用函数参数发送WHERE
子句。
有什么好的建议或例子吗?
答案 0 :(得分:1)
SQLBuilder可能对Java有用。它允许您编写动态构建sql的编译时检查的Java代码:
String selectQuery =
(new SelectQuery())
.addColumns(t1Col1, t1Col2, t2Col1)
.addJoin(SelectQuery.JoinType.INNER_JOIN, joinOfT1AndT2)
.addOrderings(t1Col1)
.validate().toString();
答案 1 :(得分:1)
PL / SQL对于创建动态SQL并不愉快,因为你发现它的字符串操作很痛苦。您可以从客户端发送where子句,但是您必须确保检查SQL注入,即确保短语以“where”开头,没有分号或仅在末尾(如果它可能出现在中间)你需要从字符串分隔符查看,只允许它在其中),等等。另一个选项是一个存储过程,它采用字段过滤器的预定义参数列表,对参数字段为每列应用“like”。
答案 2 :(得分:0)
在PL / SQL中使用:
EXECUTE IMMEDIATE lString;
这使您可以将lString(VARCHAR2)构建到您想要使用的大多数SQL中。 e.g。
EXECUTE IMMEDIATE 'SELECT value
FROM TABLE
WHERE '||pWhereClause
INTO lValue;
您还可以在EXECUTE IMMEDIATE中返回多行并执行DDL语句。
答案 3 :(得分:0)
是的,EXECUTE IMMEDIATE也是我的朋友。谢谢你的建议。我想这次我尝试使用参数
发送WHERE子句答案 4 :(得分:0)
我认为最好将查询创建的整个逻辑放在一个地方,Java或Oracle。我认为你知道如何用Java做到这一点。在Oracle中,如果查询仅检索行,则可以使用EXECUTE IMMEDIATE ... INTO子句。
如果查询返回多行且具有单个参数(不使用IN运算符),则可以使用REF CURSOR策略循环查询结果或将游标本身返回到Java程序(如果您必须导入Oracle java clases用它)。 First Ref Cursor answer in Google
如果必须使用IN参数(或者在其他极少数情况下),则必须使用DBMS_SQL包解析查询,这个包很简单,使用起来有点棘手,但它非常灵活。 DBMS_SQL doc(在阅读方法之前观察流程图)