4

我正在使用一段简单的代码来更新 Oracle DB 中的一行,查询只更新一行,但执行仍然挂在 stmt.executeUpdate() 上。

它不会抛出任何异常,但控件只是挂在那里。

我在这里迷路了,因为同一段代码之前运行良好。

  try {
      DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
      conn = DriverManager.getConnection(url,username,pwd);
      stmt = conn.createStatement();
      String sql = "update report set status =" +"'"+NO+"'"+ " where name=" +"'"+ name+"'"+ " and user_id=" +"'"+sub+"'"; 
      System.out.println(sql);          
      stmt.executeUpdate(sql)
4

4 回答 4

13

你不应该通过像这样连接变量来创建语句。这让您对SQL 注入持开放态度。此外,Oracle 会将每个语句视为需要硬解析的新语句,这可能会导致性能问题。相反,使用preparedStatement

但是,我认为在您的情况下,这不是您的问题的原因。当一个简单的更新挂起时,几乎总是以下原因之一:

  1. 该行被另一个事务锁定。
  2. 您正在更新另一个表作为未索引外键引用的键
  3. 该表有一个执行大量工作的 ON UPDATE 触发器。

我很确定你是第一种情况。Oracle 阻止多个用户同时更新同一行,主要是出于一致性原因。这意味着如果修改的行被锁定,则 DML 语句将等待另一个事务。它将等到阻塞事务提交或回滚。

我建议您在尝试通过之前执行更新之前始终锁定一行SELECT ... FOR UPDATE NOWAIT。如果该行已经被锁定,这将失败,您可以通过告诉用户该行当前被另一个会话锁定来优雅地退出。

您还必须确保没有事务以未提交状态结束。所有会话都应在退出之前提交或回滚其更改(但不要使用自动提交)。

于 2013-08-14T12:37:39.437 回答
1

使用 JDBC PreparedStatement java 文档

  Class.forName("org.apache.derby.jdbc.ClientDriver");
  Connection con = DriverManager.getConnection
  ("jdbc:derby://localhost:1527/testDb","name","pass");
  PreparedStatement updateemp = con.prepareStatement
  ("insert into emp values(?,?,?)");
  updateemp.setInt(1,23);
  updateemp.setString(2,"Roshan");
  updateemp.setString(3, "CEO");
  updateemp.executeUpdate();
于 2013-08-14T12:01:33.387 回答
0

我遇到了同样的问题,我不知道其他人,但我通过简单地关闭 SQLplus 解决了它!我认为这不能解决它,因为一些查询在 sqlplus 在控制台上运行时有效,但我关闭了它,现在每个查询都有效,没有任何问题!

如果您遇到我们的问题,您可能想试试这个!在您的控制台或您正在使用的任何其他数据库上退出 Sqlplus,然后再次尝试运行您的代码!

于 2018-12-03T23:31:03.787 回答
-1

改用 PreparedStatement

http://www.mkyong.com/jdbc/jdbc-preparestatement-example-insert-a-record/

如果你声明,那么每次它服务器都会检查语法,所以它会消耗时间所以去 PreparedStatement

于 2013-08-14T12:02:04.553 回答