这是什么意思时的Statement.executeUpdate()返回-1?(What does i

2019-06-28 07:26发布

在管理工作室,并在作品中查询executeUpdate使得同样executeUpdate返回-1 ,这是任何文档中的不确定,我们可以找到。 它应该只返回行数或0 。 这是什么意思? 该驱动程序是JDBC-ODBC桥如果该事项。

例:

String query = "IF NOT EXISTS (SELECT * FROM animals WHERE animal_name ='" + a +"') INSERT INTO " + table + " (animal_name, animal_desc, species_id) VALUES ('" + a + "', '" + b + "', " + c + ")";
int result = statement.executeUpdate(query);
System.out.println(result);

该查询工作,作为该行被添加到数据库中,它只是奇怪的是,它返回-1,文件中表示,它只会返回0或行数(因为我已经被修正)。

更新:

在Management Studio中运行这个结果与“命令成功完成”。

IF NOT EXISTS (SELECT * FROM animals WHERE animal_name = 'a') 
INSERT INTO animals(animal_name, animal_desc, species_id) VALUES ('a', 'a', 1)

这应该意味着方法应该返回0,因为它不返回任何东西,对不对?

Answer 1:

由于执行的语句是不实际的DML(如UPDATEINSERTEXECUTE ),但一张T-SQL中包含 DML,我怀疑这是不是作为一个更新询问处理。

的JDBC 4.1规范规定的东西13.1.2.3节(而难以BTW解释):

当方法execute返回true,则方法getResultSet被调用来检索ResultSet对象。 当execute返回false,该方法getUpdateCount返回一个int。 如果这个数字大于或等于零,则表明由语句返回的更新计数。 如果是-1,则表示没有更多的结果。

鉴于这一信息,我猜executeUpdate()内部并在execute()然后-为execute()将返回false -它将返回的值getUpdateCount()在这种情况下-按照JDBC规范-将返回-1

这是由事实1)适用于Javadoc进一步证实Statement.executeUpdate()说:

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

2)对于的Javadoc Statement.getUpdateCount()规定:

当前结果作为更新计数; -1,如果当前结果为ResultSet对象或没有更多的结果

只是为了澄清:给定的Javadoc executeUpdate()的行为可能是错误的,但它可以解释的。

此外,作为我评论其他地方,-1可能只是表明:也许有什么东西在改变,但我们根本不知道,或者我们不能给的变化(例如一个准确的数字,因为在这个例子中它是一块的T-被执行的SQL)。



Answer 2:

所以,4年后, 微软已经开源了自己的JDBC驱动程序Github上 。 我今天有一个关于这个问题的通知,并去了,一看,我相信我已经找到了罪魁祸首这里 , mssql-jdbc/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java:1713

基本上,司机试图了解SQL Server发送回来,如果它不是一个明确的结果集。 根据该意见,它是这样的:

  1. 检查错误第一次。 (LN 1669)

  2. 不是一个错误。 它是一个结果集合? (LN 1680)

  3. 不是错误或结果集。 也许从T-SQL语句的结果? 也就是说,执行下列操作之一:

    • 受影响的行的数目的正计数(从插入,更新,或删除),
    • 零表示没有行受到影响,或者语句是DDL,或
    • -1指示语句成功,但没有可用的更新计数信息 (转化为Statement.SUCCESS_NO_INFO批量更新计数阵列)。 (LN 1706)
  4. 以上都不是。 这里最后的机会......走进解析器以上,我们知道moreResults最初是真实的。 如果我们moreResults假的问世,我们打了DONE令牌(要么完成了(最终)或DONE(批次)RPC),表示该批次的整体成功,但有个别语句更新计数的信息。 这类似于上述最后一种情况下,不同的是没有更新计数。 那就是:我们有一个成功的结果(返回true),但是我们对此没有其他信息(使用UpdateCount = -1)。 (LN 1693)

  5. 只有这样,才能在这里(moreResults仍然是真实的,但没有任何一种明显的结果)是当TDSParser实际上并没有什么分析。 也就是说,我们在EOF的响应。 在这种情况下,确实是没有更多的结果。 我们就大功告成了。 (LN 1717)

(重点煤矿)

所以,你们是对的结束。 SQL根本无法知道有多少行受到了影响,并默认为-1 。 :)



Answer 3:

我还没有看到任何地方这样,无论是,但我的直觉是,这意味着, IF从执行防止整个语句。

尝试与其中一个数据库运行该语句IF通过。

还要检查是否有涉及到这可能会改变结果的任何触发器。

[编辑]当标准说 ,这个函数不应该返回-1 ,不执行此操作。 Java没有前置和后置条件。 JDBC驱动程序可以返回一个随机数,并没有办法阻止它。

如果一定要知道为什么发生这种情况是很重要的,请针对不同的数据库语句,直到你已经尝试了所有的执行路径(即一个在IF返回false ,一个地方返回true )。

如果它不是那么重要,它划掉的“巧招”由微软工程师,记得你有多喜欢它,当你觉得自己是聪明的自己下一次。



Answer 4:

针对z / OS的服务器,DB2的executeUpdate语句,返回的值取决于正在执行的SQL语句的类型:

对于能有一个更新数量,如INSERT,UPDATE或DELETE语句的SQL语句,返回的值是受影响的行数。 有可能:

一个正数,如果行的正数由操作的影响,操作是不是质量上的分段表空间中删除。

0,如果没有行被操作的影响。

-1,如果操作是一个批量删除上的分段表空间。

对于DB2 CALL语句, 则返回值-1,因为DB2数据库服务器不能确定受影响的行数。 调用getUpdateCount或getMoreResults可用于CALL语句也返回-1。 对于任何其他SQL语句,则返回值-1。



Answer 5:

这并不能解释为什么它应该是这样的,但它解释了为什么它会发生。 下面字节代码设置-1到内部updateCount在标志SQLServerStatement构造:

// Method descriptor #401 (Lcom/microsoft/sqlserver/jdbc/SQLServerConnection;II)V
// Stack: 5, Locals: 8
SQLServerStatement(
  com.microsoft.sqlserver.jdbc.SQLServerConnection arg0, int arg1, int arg2) 
throws com.microsoft.sqlserver.jdbc.SQLServerException;

// [...]

34 aload_0 [this]
35 iconst_m1
36 putfield com.microsoft.sqlserver.jdbc.SQLServerStatement.updateCount:int [27]

现在,我不会分析所有可能的控制流,但我只想说,这是内部默认初始化值,不知怎的,泄露至客户端代码。 请注意,这也是在其他方法进行:

// Method descriptor #383 ()V
// Stack: 2, Locals: 1
final void resetForReexecute() 
throws com.microsoft.sqlserver.jdbc.SQLServerException;

// [...]

10 aload_0 [this]
11 iconst_m1
12 putfield com.microsoft.sqlserver.jdbc.SQLServerStatement.updateCount:int [27]

// Method descriptor #383 ()V
// Stack: 3, Locals: 3
final void clearLastResult();
0 aload_0 [this]
1 iconst_m1
2 putfield com.microsoft.sqlserver.jdbc.SQLServerStatement.updateCount:int [27]

换句话说,你可能是安全的口译-1为同0 。 如果你靠这个结果值,也许留在安全方面,做你检查如下:

// No rows affected
if (stmt.executeUpdate() <= 0) {
}
// Rows affected
else {
}

更新 :在阅读马克Rotteveel的回答 ,我倾向于同意他的说法,假定-1“未知更新计数”的兼容JDBC的价值。 即使这不是对相关方法的Javadoc文档,它记录在JDBC规范,章节13.1.2.3返回未知或多个结果 。 在这种非常情况下,可以说,一个IF .. INSERT ..语句将有一个“未知更新计数”,因为这种说法是不SQL标准兼容反正。



文章来源: What does it mean when Statement.executeUpdate() returns -1?