如何在Java查询上使用SQL提示

时间:2018-07-18 10:03:05

标签: java sql oracle

在输入SQL查询时,刚听说过“ SQL提示”可优化查询结果或处理时间。 我已经找到了很多有关如何在Hibernate中实现此概念的信息,但是没有关于如何将其与普通Java代码一起使用的信息。 谁能帮我这个?

我们正在使用以下代码:

String value = "someValueToUseAsFilter";
String query =  "SELECT /*+ opt_param('_optimizer_cost_model','io') opt_param('optimizer_index_cost_adj',20) opt_param('optimizer_index_caching',65) PARALLEL(4)*/ "+
                        " T.field AS table_field "+
                        " FROM table T "+
                        " WHERE T.field = ? "+
                        "/";
ResultSet rs = null;
PreparedStatement stmt = null;
try {
        stmt = this.connection.prepareStatement(query);
        stmt.setQueryTimeout(this.timeout);
        stmt.setString(1, value);
        rs = stmt.executeQuery();
}
catch (Exception e){
        e.printStackTrace();        
}

接下来,eclipse引发以下异常:

java.sql.SQLSyntaxErrorException: ORA-00936: missing expression

该查询已经过测试,如果直接针对数据库启动,它将运行正常。但是在代码上使用它时,总是返回此错误。 有人可以向我解释一下吗?如果是这样,我如何在这种情况下使用它?

谢谢。

1 个答案:

答案 0 :(得分:1)

in the answer @ahorse_with_no_name linked to所述,/是用于结束并执行该语句的客户指令。您的错误与提示或Java无关,您只需要删除该斜杠即可。

您可以看到以其他方式运行语句的效果相同,例如作为匿名块中的动态SQL:

set serveroutput on
declare
  query varchar2(4000);
begin
  query := q'[
SELECT /*+ opt_param('_optimizer_cost_model','io') opt_param('optimizer_index_cost_adj',20) opt_param('optimizer_index_caching',65) PARALLEL(4)*/
T.field AS table_field
FROM your_table T
WHERE T.field = :var
/
]';
  dbms_output.put_line(query);
  execute immediate query;
end;
/

生成的语句打印为:

SELECT /*+ opt_param('_optimizer_cost_model','io') opt_param('optimizer_index_cost_adj',20) opt_param('optimizer_index_caching',65) PARALLEL(4)*/
T.field AS table_field
FROM your_table T
WHERE T.field = :var
/

带有斜杠,正如您所说的那样,它将直接在客户端/ IDE中运行;但是execute immediate遇到的错误与您相同:

ORA-00936: missing expression
ORA-06512: at line 12

仅将斜杠看作是分隔符,因此期望在其后有另一个表达式-形成子句WHERE T.field = :var / <something>

如果删除斜杠:

declare
  query varchar2(4000);
begin
  query := q'[
SELECT /*+ opt_param('_optimizer_cost_model','io') opt_param('optimizer_index_cost_adj',20) opt_param('optimizer_index_caching',65) PARALLEL(4)*/
T.field AS table_field
FROM your_table T
WHERE T.field = :var
]';
  dbms_output.put_line(query);
  execute immediate query using 42;
end;
/

生成的语句现在(显然)没有它,并且您不会收到错误:

PL/SQL procedure successfully completed.

(我应该在中选择-在此处仅解析查询,不执行查询,但是对于此示例而言,没关系)。

请注意,在语句末尾也不需要分号,因为这是一个语句分隔符。添加一个将导致另一个错误,例如ORA-00911无效字符。