11

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

我喜欢这样:

boolean isResultSet = statement.execute(arbitrarySQLCommand);

我可以得到该getUpdateCount()方法影响的行数。没关系。我遇到的问题是更新计数为零时。这可能意味着:

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

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

我想要的是能够区分上述情况 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. 如果那个词(忽略大小写)是 INSERT、UPDATE 或 DELETE,那么它是一个 DML 语句并且输出getUpdateCount()是相关的,否则输出getUpdateCount()是不相关的。

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

4

2 回答 2

7

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

Set<String> dmlCommands = new HashSet<String>() {
  {
    add("UPDATE"); add("INSERT"); add("DELETE"); //Add more DML commands ....
  }
};
int updateCount = statement.getUpdateCount();
for(String dml : dmlCommands) {
    if(arbitrarySQLCommand.toUpperCase().contains(dml) && updateCount == 0) {
        updateCount = -1;
        break;
    }
}
于 2013-07-09T09:43:15.233 回答
6

也许我的回答并不能帮助您解决您的确切问题,但是当我搜索如何在运行 DML 后获取受影响的行数时,我到了这里,没有找到行数 - 使用 MySQL。我在这里写下我发现可以帮助别人的东西。

我的问题是,当我运行一个不对表进行任何更改的语句时,例如

UPDATE table SET field=1 WHERE field=1

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

要更改这一点,应在创建连接时在 url 中提供一个选项( with 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

于 2014-01-11T21:19:33.070 回答