pl sql & java - 创建动态查询

Posted

技术标签:

【中文标题】pl sql & java - 创建动态查询【英文标题】:pl sql & java - creating dynamic query 【发布时间】:2008-09-23 18:14:30 【问题描述】:

我进退两难,我正在使用 Java 和 Oracle,并试图在 PL/SQL 端保留查询。一切都很好,直到我有这些可能有也可能没有条件的复杂查询。

在Java 中将WHERE 子句与条件放在一起并不难,但这并不好。 在 PL/SQL 方面,我还发现 dynamic queries 的唯一可能性是像

这样的字符串操作
IF inputname IS NOT NULL THEN    
    query := query ||' and NAME=' || inputname; 
END IF;

现在我在想,我将在 PL/SQL 中留下查询并发送带有函数参数的 WHERE 子句。 请问有什么好的建议或例子吗?

【问题讨论】:

如果你提供更多关于你的查询的细节,我可以给你一个更合适的例子。 为什么要增加复杂性? PL/SQL 适用于某些事情,但不适用于大量小查询。 这是我添加条件的查询的一部分,在此之前是许多连接,之后是按顺序分组,棘手的部分是获取正确的行 【参考方案1】:

SQLBuilder 在 Java 方面可能对您有用。它允许您编写动态构建 sql 的编译时检查 Java 代码:

String selectQuery =
  (new SelectQuery())
  .addColumns(t1Col1, t1Col2, t2Col1)
  .addJoin(SelectQuery.JoinType.INNER_JOIN, joinOfT1AndT2)
  .addOrderings(t1Col1)
  .validate().toString();

【讨论】:

【参考方案2】:

正如您所发现的,PL/SQL 不适合创建动态 SQL,它的字符串操作很痛苦。您可以从客户端发送 where 子句,但您必须确保检查 SQL 注入,即确保该短语以“where”开头,没有分号或仅在末尾(如果它可能出现在中间您需要从字符串分隔符中查看并只允许在其中使用)等。另一种选择是存储过程,它采用字段过滤器的预定义参数列表,对参数字段的每一列应用“喜欢”。

【讨论】:

【参考方案3】:

在 PL/SQL 中使用:

EXECUTE IMMEDIATE lString;

这使您可以将 lString(一个 VARCHAR2)构建到您想要使用的大多数 SQL 位中。例如

  EXECUTE IMMEDIATE 'SELECT  value
                     FROM    TABLE
                     WHERE   '||pWhereClause
  INTO    lValue;

您还可以在 EXECUTE IMMEDIATE 中返回多行并执行 DDL 语句。

【讨论】:

我不认为 EXECUTE IMMEDIATE 可以检索多行【参考方案4】:

是的,EXECUTE IMMEDIATE 也是我的朋友。感谢您的建议。我想这次我尝试只发送带参数的 WHERE 子句

【讨论】:

【参考方案5】:

我认为最好将查询创建的整个逻辑放在一个地方,Java 或 Oracle。我假设你知道如何在 Java 中做到这一点。在 Oracle 中,如果查询只检索一行,您可以使用 EXECUTE IMMEDIATE ... INTO 子句。

如果查询返回多行且有单个参数(不使用 IN 运算符),您可以使用 REF CURSOR 策略循环查询结果或将游标本身返回给 Java 程序(如果您必须导入 Oracle java 类用它)。 First Ref Cursor answer in Google

如果您必须使用 IN 参数(或在其他极少数情况下),您必须使用 DBMS_SQL 包解析查询,这太冗长且使用起来有点棘手,但它非常灵活。 DBMS_SQL doc(阅读方法前先看流程图)

【讨论】:

以上是关于pl sql & java - 创建动态查询的主要内容,如果未能解决你的问题,请参考以下文章

通过 Web 界面在 Java 中执行动态 sql 和 pl/sql

创建一个表,其中动态 PL/SQL 中的“日期条件”

带有动态 sql 的 PL/SQL 触发器

如何根据表名作为输入在 PL/Sql 中动态创建记录

动态SQL和PL/SQL的EXECUTE选项分析

PL SQL - 使用动态 SQL 生成删除语句