Statement batch doesn't produce the correct number of update counts
See original GitHub issueBug Report
Versions
- Driver: 0.9.0.M1
- Database: Microsoft SQL Server 2019 (RTM-CU8-GDR) (KB4583459) - 15.0.4083.2 (X64) Nov 2 2020 18:35:09 Copyright © 2019 Microsoft Corporation Express Edition (64-bit) on Linux (Ubuntu 18.04.5 LTS) <X64>
- Java: openjdk version “11.0.9.1” 2020-11-04
- OS: Microsoft Windows [Version 10.0.19042.867]
Current Behavior
This code:
System.out.println((
Flux.from(connectionFactory.create())
.flatMap(c -> c
.createStatement("DECLARE @t TABLE(i INT);\n"
+ "INSERT INTO @t VALUES (1),(2),(3);\n"
+ "SELECT * FROM @t;\n")
.execute())
.flatMap(it -> {
System.out.println("IT: " + it);
return it.getRowsUpdated();
})
.collectList()
.block()
));
Prints:
IT: io.r2dbc.mssql.MssqlResult@3df5a869
[6]
Expected behavior/code
I would expect the same behaviour as in JDBC. Here’s a loop that collects both update counts and result sets:
try (Statement s = connection.createStatement()) {
boolean b = s.execute("DECLARE @t TABLE(i INT);\n"
+ "INSERT INTO @t VALUES (1),(2),(3);\n"
+ "SELECT * FROM @t;\n");
while (true) {
int c = -1;
if (b) {
try (ResultSet rs = s.getResultSet()) {
while (rs.next())
System.out.println("rs: " + rs.getInt(1));
}
}
else
c = s.getUpdateCount();
System.out.println(b + ": " + c);
if (!b && c == -1)
break;
else
b = s.getMoreResults();
}
}
Printing:
false: 3
rs: 1
rs: 2
rs: 3
true: -1
false: -1
The JDBC version actually checks whether the current result is an update count or a result set (this isn’t currently possible with R2DBC, see https://github.com/r2dbc/r2dbc-spi/issues/27). But even if we embed this knowledge into the reactive version, I’m not getting the right results:
AtomicInteger i = new AtomicInteger(0);
System.out.println((
Flux.from(connectionFactory.create())
.flatMap(c -> c
.createStatement("DECLARE @t TABLE(i INT);\n"
+ "INSERT INTO @t VALUES (1),(2),(3);\n"
+ "SELECT * FROM @t;\n")
.execute())
.flatMap(it -> {
System.out.println("IT: " + it);
if (i.getAndIncrement() == 0)
return it.getRowsUpdated();
else
return it.map((r, m) -> r.get(0));
})
.collectList()
.block()
));
This still prints the wrong thing
Possible Solution
As a workaround, it seems I can use a formal batch, not the statement batch syntax (though, behind the scenes, I would imagine these should be the same thing):
System.out.println((
Flux.from(connectionFactory.create())
.flatMap(c -> c.createBatch()
.add("DECLARE @t TABLE(i INT);")
.add("INSERT INTO @t VALUES (1),(2),(3);\n")
.add("SELECT * FROM @t;\n")
.execute())
.flatMap(it -> {
System.out.println("IT: " + it);
return it.getRowsUpdated();
})
.collectList()
.block()
));
Producing:
IT: io.r2dbc.mssql.MssqlResult@134650ed
IT: io.r2dbc.mssql.MssqlResult@2463bd0a
[3, 3]
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
ORACLE JDBC Batch execution doesn't return actual count of ...
For a callable statement batch, the server always returns the value 1 as the update count, irrespective of the number rows affected by...
Read more >Problem in getting update records count while executeBatch()
Case 1: I added these statements as addBatch() & at the end i execute method " executeBatch()". It returned the array of integer...
Read more >Working with SQL Server ROWCOUNT - SQLShack
SET ROWCOUNT is a system object that enforces the SQL Server Engine to stop processing the query after the specified number of rows...
Read more >MySQL 8.0 Reference Manual :: 13.2.17 UPDATE Statement
UPDATE is a DML statement that modifies rows in a table. An UPDATE statement can start with a WITH clause to define common...
Read more >Documentation: 15: UPDATE - PostgreSQL
The count is the number of rows updated, including matched rows whose values did not change. Note that the number may be less...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The problem with variable identification is somewhat that we can’t know whether something is a variable because a lot of things in the SQL server universe start with
@
(DECLARE @
,SELECT @@…
). I think that’s a general bug in the RPC result handling. Feel free to create another ticket to align Batch vs. non-batch result behavior. We can use this one to fix theResult
behavior observed fromBatch
.Confirming that
Batch
works as expected whilecreateStatement(…)
doesn’t split up theResult
:Batch
createStatement(…).execute()