如何判断 JDBC 执行中更改的行数

问题描述 投票:0回答:3

我不确定如何获取 SQL 执行影响的行数。

我确实喜欢这个:

boolean isResultSet = statement.execute(arbitrarySQLCommand);

我可以得到受

getUpdateCount()
方法影响的行数。那就好了。我遇到的问题是更新计数为零时。这可能意味着:

  1. 这是一个DML语句,但它没有影响任何行。受影响的零行是有效响应。我只是说有些条件没有满足。

  2. 这是一个非 DML 语句(最有可能是 DDL 语句).. 根据定义,它不会更改行,因此更新计数始终为零(废话!)。或者换句话说:更新计数的概念对于此类语句来说是没有意义的。

我希望能够区分上述情况 1 和 2 。怎么办?

我对产生输出的语句不感兴趣,因此我也可以使用 executeUpdate() 但据我所知,该方法的返回值具有相同的缺陷:

退货:

(1) SQL 数据操作语言 (DML) 语句的行计数或 (2) 0(不返回任何内容的 SQL 语句)

啊啊啊!
我希望是这样:

退货:

(1) SQL 数据操作语言 (DML) 语句的行计数或 (2) -1 表示不返回任何内容的 SQL 语句



(注:我事先并不知道

arbitrarySQLCommand
的内容)



最终选择的解决方案

似乎没有一个真正的类似 JDBC 的解决方案来解决这个问题。在我看来,JDBC 的设计者在

getUpdateCount
上犯了一个严重的错误,他们使用值 0(零)来表示不(根据定义)影响行的语句,因为受影响的零行也是完全有效的值DML 语句的结果。

唯一可能的解决方案似乎是对 SQL 语句进行某种模式匹配,以确定它是 DML 语句(INSERT、UPDATE、DELETE)还是其他类型的 SQL 语句。像这样的东西:

  1. arbitrarySQLCommand
    中提取第一个单词。一个词被终止 由空格或 EOL 行字符组成。
  2. 如果那个词(忽略 case) 是 INSERT、UPDATE 或 DELETE 那么它是 DML 语句 并且
    getUpdateCount()
    的输出是相关的,否则
    getUpdateCount()
    的输出无关紧要。

丑陋且容易出错。但这是这个问题中唯一可能的解决方案。 :-(

java jdbc
3个回答
8
投票

也许我的答案并不能帮助您准确地回答您的问题,但是当我搜索如何在运行 DML 后获取“受影响的”行计数时,我来到了这里,而不是“找到”行计数 - 使用 MySQL。我在这里写下我发现的可以帮助他人的内容。 我的问题是,例如,当我运行一条不会对表进行任何更改的语句时 UPDATE table SET field=1 WHERE field=1

方法

Statement.executeUpdate(...)
返回找到的行数,而不是已更改/受影响的行数。所以我无法判断查询是否修改了表中的某些内容。

要更改此设置,应在创建连接时在 url 中提供一个选项(使用

DriverManager.getConnection()
),如下所示:

jdbc:mysql://${jdbc.host}/${jdbc.db}?

useAffectedRows=true



我在这里找到的:

http://mybatis-user.963551.n3.nabble.com/Return-number-of-changed-rows-tp3888464p3903155.html

和 MySQL 文档:

https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html

你能做的最好的事情就是检查 SQL 语句


7
投票

我遇到了以下场景...有些查询使用了多个 
UPDATE

0
投票
UPDATE user SET name="nameXXX" WHERE id="XXXX1'; UPDATE user SET email="emailXXX" WHERE id="XXXX2";

Statement stmt = connection.createStatement();
var isResultSet = stmt.execute(sqlQuery);
当我访问

stmt.getUpdateCount()
时,我仅获得受第一个
UPDATE

影响的行数。为了解决这个问题,我做了以下

        int totalAffectedRows = 0;
        do {
            if (!isResultSet) {
                int affectedRows = stmt.getUpdateCount(); 
                if (affectedRows != -1) { 
                    totalAffectedRows += affectedRows;
                }
            }
            isResultSet = stmt.getMoreResults();
        } while (isResultSet || stmt.getUpdateCount() != -1);
    

© www.soinside.com 2019 - 2024. All rights reserved.