在管理工作室,并在作品中查询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(如UPDATE
, INSERT
或EXECUTE
),但一张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发送回来,如果它不是一个明确的结果集。 根据该意见,它是这样的:
检查错误第一次。 (LN 1669)
不是一个错误。 它是一个结果集合? (LN 1680)
不是错误或结果集。 也许从T-SQL语句的结果? 也就是说,执行下列操作之一:
- 受影响的行的数目的正计数(从插入,更新,或删除),
- 零表示没有行受到影响,或者语句是DDL,或
- -1指示语句成功,但没有可用的更新计数信息 (转化为Statement.SUCCESS_NO_INFO批量更新计数阵列)。 (LN 1706)
以上都不是。 这里最后的机会......走进解析器以上,我们知道moreResults最初是真实的。 如果我们moreResults假的问世,我们打了DONE令牌(要么完成了(最终)或DONE(批次)RPC),表示该批次的整体成功,但有个别语句更新计数的信息。 这类似于上述最后一种情况下,不同的是没有更新计数。 那就是:我们有一个成功的结果(返回true),但是我们对此没有其他信息(使用UpdateCount = -1)。 (LN 1693)
只有这样,才能在这里(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?