如何捕获结果集循环内的约束违规?

发布于 2024-12-09 19:50:39 字数 1229 浏览 0 评论 0原文

我正在开发一个 servlet,它将生成唯一的代码并在 mySQL 数据库中更新该代码。 现在,我想捕获 mySQL 表中已存在唯一代码时引发的任何异常,并生成新代码并尝试更新数据库。问题是我想在 for 循环本身中执行此操作。代码如下:

    try
    {
    connection = datasource.getConnection();
    SQLUpdate = "INSERT INTO Voucher_dump VALUES( '"+unique_code+"','08-10-2011 04:48:48','0')";
      PreparedStatement ps1 = connection.prepareStatement(SQLUpdate);
      ps1.executeUpdate();
      ResultSet r = ps1.getResultSet(); // this is where I'm checking if it's a duplicate
      if(r==null)
          out.println("This is a duplicate");
      else out.println("Updated");
      trial12= "08-10-2011 04:48:480.03999855056924717a";
      SQLUpdate = "INSERT INTO Voucher_dump VALUES( '"+trial12+"','08-10-2011 04:48:48','0')";

      ps1 = connection.prepareStatement(SQLUpdate);
      ps1.executeUpdate();
      r = ps1.getResultSet();
      if(r==null)
          out.println("This is a duplicate");
      else out.println("Updated");

    }
    catch (SQLException sqle)
    {
        sqle.printStackTrace();
    }

我不想等到整个循环结束才捕获SQLException(我已经在mySQL中将这个键定义为primary)。此时,结果作为重复条目返回,我想重新生成此密钥并再次尝试更新。我的输出页面上此特定代码的输出为空白(所有其他参数均正确显示)。既不显示“这是重复项”,也不显示“已更新”。也许,ResultSet 不是最好的方法。你们能给我一些关于什么是最好的前进方向的建议吗?

I was working on a servlet that will generate a unique code and update that in a mySQL database.
Now, in that, I want to catch any exception thrown in case that unique code already exists in the mySQL table and generate a new code and try updating the database. The problem is I want to do this WITHIN the for loop itself. The code is as follows:

    try
    {
    connection = datasource.getConnection();
    SQLUpdate = "INSERT INTO Voucher_dump VALUES( '"+unique_code+"','08-10-2011 04:48:48','0')";
      PreparedStatement ps1 = connection.prepareStatement(SQLUpdate);
      ps1.executeUpdate();
      ResultSet r = ps1.getResultSet(); // this is where I'm checking if it's a duplicate
      if(r==null)
          out.println("This is a duplicate");
      else out.println("Updated");
      trial12= "08-10-2011 04:48:480.03999855056924717a";
      SQLUpdate = "INSERT INTO Voucher_dump VALUES( '"+trial12+"','08-10-2011 04:48:48','0')";

      ps1 = connection.prepareStatement(SQLUpdate);
      ps1.executeUpdate();
      r = ps1.getResultSet();
      if(r==null)
          out.println("This is a duplicate");
      else out.println("Updated");

    }
    catch (SQLException sqle)
    {
        sqle.printStackTrace();
    }

I don't want to wait till the end of the entire loop to catch the SQLException (I have already defined this key in mySQL as primary). The moment, the result comes back as a duplicate entry, I want to re-generate this key and attempt the update again.My output for this particular code is coming blank on my output page (all other parameters are showing correctly). Neither is "This is a duplicate" displayed nor is "Updated". Maybe, ResultSet is not the best way to do it. Could you guys give me some advice on what would be the best way forward ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只等公子 2024-12-16 19:50:39

一些建议(排名不分先后):

  1. 在finally 块中关闭连接。
  2. 如果您要在关闭连接之前创建许多语句,请单独关闭语句。 (“许多”由您的 DBA 定义。)
  3. 格式化您的代码。
  4. 不要使用实际代码中的 stdout 和/或 stderr。选择一个日志框架。
  5. 考虑使用一些辅助类来简化(并纠正)数据库访问,例如 Spring 的 JdbcTemplate
  6. 确保在发布示例代码时包含相关上下文。

由于 #6,我不知道 out 是什么,但我怀疑您没有看到任何内容的原因是您在第一个语句中插入了重复的值,这将导致SQLException 来自该行,而不是您期望的 getResultSet() 处。由于错误已写入 stdout,因此它会显示在服务器日志中的某个位置,但不会向 out 写入任何内容。我不确定为什么您认为 getResultSet() 将返回 null 或非 null,具体取决于是否存在约束违规。查看 javadoc该方法

更新: 7. 正如 BalusC 指出的,永远、永远将字符串直接连接到 JDBC 语句中。使用PreparedStatment的占位符和set*方法。有关 SQL 注入的信息,请参阅 WikipediaXKCD.

Some advice in no particular order:

  1. Close the connection in a finally block.
  2. Close statements individually if you'll be creating many of them before closing the connection. ("Many" is defined by your DBAs.)
  3. Format your code.
  4. Don't use stdout and/or stderr from real code. Pick a logging framework.
  5. Consider using some helper classes to simplify (and correct) your database access, like Spring's JdbcTemplate.
  6. Make sure to include relevant context when you post example code.

Due to #6, I don't know what out is, but I suspect the reason you're not seeing anything is that you're inserting a duplicate value with the first statement, which will cause a SQLException from that line, not at getResultSet(), where you seem to expect it. Since the error is written to stdout, it'll show up in your server logs somewhere, but nothing will be written to out. I'm not sure why you think getResultSet() will return null or not null depending on whether there was a constraint violation. Take a look at the javadoc for that method.

Update: 7. As BalusC points out, never, ever concatenate a string directly into a JDBC Statment. Use PreparedStatment's placeholders and set* methods. For info on SQL injection, see Wikipedia and XKCD.

别挽留 2024-12-16 19:50:39

这段代码怎么样?

try {
            Class.forName(driver).newInstance();
            conn = DriverManager.getConnection(url + dbName);
            System.out.println("Connected to the database");
            int i = 1;                                     //get the unique code
            boolean isInserted = false;
            while (!isInserted) {
                try {
                    PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO test values (?)");
                    preparedStatement.setInt(1, i);
                    preparedStatement.executeUpdate();
                    isInserted = true;
                } catch (com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException e) {   //Catch the particular exception which throws error on unique constraint. This may depend on Java/MySQL your version 
                    i++;                         //get the next unique code
                }
            }

            System.out.println("Disconnected from database");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (Exception e) {
            }
        }

How about this code?

try {
            Class.forName(driver).newInstance();
            conn = DriverManager.getConnection(url + dbName);
            System.out.println("Connected to the database");
            int i = 1;                                     //get the unique code
            boolean isInserted = false;
            while (!isInserted) {
                try {
                    PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO test values (?)");
                    preparedStatement.setInt(1, i);
                    preparedStatement.executeUpdate();
                    isInserted = true;
                } catch (com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException e) {   //Catch the particular exception which throws error on unique constraint. This may depend on Java/MySQL your version 
                    i++;                         //get the next unique code
                }
            }

            System.out.println("Disconnected from database");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (Exception e) {
            }
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文