具有Oracle效率的Java PreparedStatement?

时间:2014-06-13 15:48:48

标签: java sql oracle sqlexception

我正在开发一个从远程Web服务中提取数据的应用程序。然后将其推送到Oracle数据库。

现在,数据是基于事件的,因此它可以是INSERT / UPDATE或DELETE。为此,我创建了一个prepareStatement&的单个对象。然后根据事件类型,代码创建一个String&将其分配到准备好的声明中。

现在,对于每个检索到的事件,oracle上的表名可能会发生变化。因此查询,因此在检索每个事件之后,基于完成操作的表创建字符串&然后传递给preparedStatement对象&执行。

但是,我有2个问题 -

  1. 我想,我没有有效地使用预准备语句,因为每次查询更改时都不确定prepareStatement的Db缓存机制在这种情况下是否有用。

  2. 此外,我的所有语句都是INSERT,UPDATE或DELETE,所以我使用的是pstmt.executeUpdate(),现在它返回受操作影响的行数。但是,我得到“最大打开游标扩展错误”...我读了很多线程&因为我的陈述没有返回结果集,&每次操作后关闭preparedstatement效率不高,不确定如何处理此错误。我可以增加数据库中的开放游标数,但不会修复应用程序,因为这可能只会延迟错误,直到遇到错误的情况。

  3. getEvents()

    for ( i = 0 -> lastevent)
    {
    
      if (event == condition1)
      {
        Process.condition1(arg1, arg2)
      }
      else if (event == condition2)
      {
        Process.condition2(arg1, arg2)
      }
      .
      .
      .
    }
    
    pstmt.close();
    connection.close();
    

    流程类

    {
      condition1(arg1, arg2)
      {
        sqlstatement = "INSERT INTO Table1 (column1, column2, column3,...) VALUES (?, ?, ?);"
    
    pstmt = connection.prepareStatement(sqlstatement);
    
    pstmt.setString(1, value1);
    
    pstmt.setInt(2, value2);
    .
    .
    .
    
    pstmt.executeUpdate();
    
    connection.commit();
    
    return;
    
    }
    
    condition2(arg1, arg2)
      {
        sqlstatement = "INSERT INTO Table2 (column1, column2, column3,...) VALUES (?, ?, ?);"
    
    pstmt = connection.prepareStatement(sqlstatement);
    
    pstmt.setString(1, value1);
    
    pstmt.setInt(2, value2);
    .
    .
    .
    
    pstmt.executeUpdate();
    
    connection.commit();
    
    return;    
    
    }
    }
    

    对不起,我想,上面可能会对整个过程的完成情况有所了解......我没有把实际的代码放在其中,因为它非常分布在各个类中。它从远程服务获取位置参数的数据。但上面是它是如何完成的总结形式。

    另外,一种想法可能是在列表和列表中采取类似类型的事件。然后处理它,但我的业务要求是&远程服务提供数据的方式更容易出错。

    此外,oracle& amp;的某些表格中有130多列。该代码将每15分钟处理150多个事件。

1 个答案:

答案 0 :(得分:0)

无法“将查询字符串分配给预准备语句”。使用查询字符串创建预准备语句,如代码中所示:每次调用connection.prepareStatement(sqlstatement)都会创建一个新的预准备语句。这也是“太多打开游标”错误发生的原因:以前创建的pstmt永远不会关闭。

要重新使用预准备语句,请实例化Process类并为其提供一个init方法(以及相应的close方法),该方法被调用一次以设置可能准备好的语句使用(并在工作完成时关闭):

PreparedStatement insertTable1;
PreparedStatement insertTable2;

void init(Connection c) {
    insertTable1 = c.prepareStatement(INSERT_TABLE1_QUERY);
    insertTable2 = c.prepareStatement(INSERT_TABLE2_QUERY);
}
void close() {
    insertTable1.close();
    insertTable2.close();
}
void condition1(Connection c, arg1, arg2) {
    insertTable1.setString(1, value1);
    insertTable1.setInt(2, value2);
    insertTable1.executeUpdate();
    c.commit();
}
void condition2(Connection c, arg1, arg2) {
    insertTable2.setString(1, value1);
    insertTable2.setInt(2, value2);
    insertTable2.executeUpdate();
    c.commit();
}