【问题标题】:Writing an anonymous PL/SQL block with bind variables using JDBC使用 JDBC 编写带有绑定变量的匿名 PL/SQL 块
【发布时间】:2013-11-07 14:40:06
【问题描述】:

我有一个匿名 PL/SQL 块,其中包含我想通过 JDBC 运行的绑定变量。

PL/SQL 块示例:

variable v_value number
declare
v_return varchar2(30);
begin
:v_value:=300;
select ename into v_return from emp where empno=:v_value;
end;

相应的 Java 代码将使用带有 "?" 的转义语法来设置变量。所以这个块看起来像这样(如果我错了,请纠正我):

String block = "declare v_return varchar2(30);" +
               "begin" + 
               "? := 300;" +
               "select ename into v_return from emp where empno = ?;" +
               "end;"

现在,假设我的变量是一个 INPUT 参数,我必须像这样设置参数:

// omitting the CallableStatement and conn declarations
cs = conn.prepareCall(block);

cs.setInt(parameterIndex, parameterValue);

问题是在我的块中我有两个 "?" 用于替换绑定参数:v_value。这意味着当使用转义语法时,只会设置第一个 "?"。第二个 "?" 将被“挂起”。

在这种情况下,当同一个绑定变量在一个 PL/SQL 块中多次使用时,我应该如何在 JDBC 转义语法中进行翻译?

编辑:

我在 SO 上找到了这个与我的问题有关的 question。我从中了解到的是,我必须 REWRITE 在同一块中使用多个绑定变量实例的所有匿名 PL/SQL 块。有什么解决方法吗?或者这就是它...游戏结束...这是 JDBC 的工作方式,我必须按时完成。



期待答案...搜索了 2 小时没有结果。

【问题讨论】:

  • 您是否也转到了 Google 搜索结果的第二页?在你去那里之前,我不相信你真的绝望!

标签: java oracle jdbc plsql


【解决方案1】:

试试这个查询:

String block = "declare " +
               "   v_return varchar2(30);" +
               "begin" + 
               "   select ename into v_return from emp where empno = ?;" +
               "   ? := v_return; " +
               "end;";
CallableStatement cs = connection.prepareCall( block );
cs.setInt( 1, v_value );
cs.registerOutParameter( 2, java.SQL.VARCHAR );
cs.executeUpdate();
String result = cs.getString( 2 );

有关更多详细信息和示例,请参见以下链接:
http://docs.oracle.com/cd/E11882_01/java.112/e16548/getsta.htm#JJDBC28075
http://docs.oracle.com/cd/E11882_01/java.112/e16548/oraint.htm#JJDBC28168

【讨论】:

  • 我已经阅读了 Oracle 文档,但它们对我的情况没有帮助。您的示例适用于 2 个绑定变量(IN 和 OUT)。我给出的示例使用了一个带有一个 IN 绑定变量的 PL/SQL 块,该变量使用了两次。只有在 OUT 或 INOUT 的情况下我们才需要注册参数。
  • 请解释一下,也许我错过了一些东西 - 为什么你想运行 SELECT 查询,但不想检索不是结果?这对我来说没有意义 - 如果我不想得到查询结果,我只是......根本不运行它。
  • 这只是一个例子......我是否检索结果并不重要。要点是:在 PL/SQL 块中存在多个 SAME 绑定变量实例的情况下,如何使用 JDBC 占位符?您注册参数的解决方案对问题没有帮助。
【解决方案2】:

看看这个doc

基本上,您可以像这样绑定与输入和输出相同的变量:

CallableStatement call = conn.prepareCall(
    "{CALL doubleMyInt(?)}");
// for inout parameters, it is good practice to
// register the outparameter before setting the input value
call.registerOutParameter(1, Types.INTEGER);
call.setInt(1,10);

希望对你有帮助。

【讨论】:

  • 感谢您的努力,我不知道您可以这样做,所以 +1 ......但这对我的情况没有帮助。请重读我的问题(粗体字)。
  • 这个想法是,在某些情况下,您需要运行一个仅声明 IN 参数的 PL/SQL 块,然后进行一些其他操作,然后您检索结果(有时不需要完全检索它们)。听起来很奇怪,我知道,但从 DBA 的角度来看,它不是(顺便说一句,我不是 DBA)。
  • 我现在看到了你的问题,是的......我不知道如何让 jdbc 意识到变异绑定变量。像这样编写可调用语句通常是一个坏主意,因此重写 plsql 代码是您的最佳选择。或者,效率较低的方法是创建多个数据库调用:一种是找出您的绑定变量将获得什么值(在您的示例中为 300),另一种是将其绑定到 where 子句
  • 是的,这正是我最终(实际上是 DBA)所做的。
猜你喜欢
  • 2014-07-18
  • 1970-01-01
  • 2014-09-30
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多