Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Cursor.nextset() does not update rowcount for the next result

Aperta Adatta ai principianti
#863 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

@phelipelui ci sta già lavorando.

Dal 24/10/2026.

  • #864 di @phelipelui — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
82/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python, sql
Ambito
backend, database

Direzione di ricerca

Inizia da Cursor_nextset e dall’implementazione di execute() per confrontare come ciascuno aggiorna rowcount; l’issue nomina questi punti di ingresso, ma non i relativi percorsi dei file. Poi leggi i test esistenti del cursore in tests/test_004_cursor.py e aggiungi test per conteggi successivi di righe interessate e un set di risultati. Il lavoro è terminato quando rowcount riflette ogni risultato dopo nextset() ed è -1 per un set di risultati.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

triage needed
Describe the bug

After Cursor.nextset() moves to the next result of a multi-statement batch, Cursor.rowcount still holds the value set by execute() for the first statement. The affected-row count of every later INSERT/UPDATE/DELETE in the batch therefore cannot be read through the DB API.

nextset() calls SQLMoreResults and refreshes description and messages, but it never calls SQLRowCount, unlike execute(). pyodbc refreshes rowcount there (Cursor_nextset calls SQLRowCount after SQLMoreResults), and nextset()'s docstring cites pyodbc parity.

This matters most for T-SQL batches with control flow. A WHILE loop that inserts rows sends one result per INSERT, and the only way to count the rows the batch changed is to read rowcount after each nextset(). Tools that report "N rows affected" per batch (migration runners, deployment CLIs) under-report, and a loop that inserted 5 rows shows 0 or 1.

No exception is raised.

To reproduce
import mssql_python
from mssql_python import ddbc_bindings

conn = mssql_python.connect(
    "Server=localhost,1433;Database=tempdb;UID=sa;PWD=<password>;"
    "Encrypt=yes;TrustServerCertificate=yes;"
)
cur = conn.cursor()
cur.execute("CREATE TABLE #t (id INT)")

cur.execute("""
    INSERT INTO #t VALUES (1);
    INSERT INTO #t VALUES (2), (3);
    UPDATE #t SET id = id + 10;
""")
seen = [cur.rowcount]
native = [ddbc_bindings.DDBCSQLRowCount(cur.hstmt)]
while cur.nextset():
    seen.append(cur.rowcount)
    native.append(ddbc_bindings.DDBCSQLRowCount(cur.hstmt))

print("cursor.rowcount:", seen)    # [1, 1, 1]
print("SQLRowCount:    ", native)  # [1, 2, 3]

With a loop, every INSERT of the WHILE is its own result:

cur.execute("""
    DECLARE @i INT = 1;
    WHILE @i <= 3
    BEGIN
        INSERT INTO #t SELECT TOP (@i) n FROM (VALUES (1), (2), (3)) AS v(n);
        SET @i = @i + 1;
    END;
""")
counts = [cur.rowcount]
while cur.nextset():
    counts.append(cur.rowcount)
print(counts)  # [1, 1, 1] -- expected [1, 2, 3]
Expected behavior

After each nextset() that returns True, rowcount reflects the result the cursor is now on, the same way it does after execute():

  • the affected-row count for an INSERT/UPDATE/DELETE/MERGE result;
  • -1 for a result set, which fetch*() then updates as it does today.

For the first example that is [1, 2, 3]. This matches pyodbc on the same batch.

Further technical details
  • Python version: 3.12
  • mssql-python: 1.16.0 (also seen on 1.4.0; the code on main at bd0aaf89 is the same)
  • SQL Server version: SQL Server 2022 (16.0.4305.5, RTM-CU27-GDR)
  • Operating system: Debian 12 (bookworm), in a container

Additional context

A fix is ready, and I can open a PR for it. After the describe step, nextset() would set rowcount the same way execute() does: -1 when the new result has columns, otherwise DDBCSQLRowCount(self.hstmt). It comes with two regression tests in tests/test_004_cursor.py.

I did not look at AsyncCursor.nextset(), which goes through py-core and may need its own check.

Lingua principale
Python
Stelle
481
Fork
62
Merge medio
2g 9h
PR unite (30g)
11

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/mssql-python

Tutte le issue di microsoft/mssql-python

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.