Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

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

Aberta Para iniciantes
#863 1 comentário 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 2 dias

@phelipelui já está trabalhando nisso.

Desde 24/10/2026.

  • #864 de @phelipelui — aberto

Avaliação

Dificuldade
2/5
Tempo estimado
1-3 horas
Facilidade para iniciantes
82/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
python, sql
Domínio
backend, database

Direção de pesquisa

Comece por Cursor_nextset e pela implementação de execute() para comparar como cada um atualiza rowcount; a issue nomeia esses pontos de entrada, mas não os caminhos dos arquivos. Em seguida, leia os testes existentes do cursor em tests/test_004_cursor.py e adicione cobertura para contagens sucessivas de linhas afetadas e um conjunto de resultados. O trabalho está concluído quando rowcount refletir cada resultado após nextset() e for -1 para um conjunto de resultados.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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.

Linguagem predominante
Python
Estrelas
481
Forks
62
Merge médio
2d 9h
PRs com merge (30d)
11

Preparar o ambiente

Abrir no Codespaces

Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de microsoft/mssql-python

Todas as issues de microsoft/mssql-python

Issues semelhantes

Mais issues de Python

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.