Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

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

未关闭 适合新手
#863 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 2 天内回复

@phelipelui 已经在做这个了。

开始于 2026年10月24日。

  • #864 来自 @phelipelui —— 未关闭

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
82/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python, sql
领域
backend, database

调研方向

从 Cursor_nextset 和 execute() 的实现开始,比较它们各自如何刷新 rowcount;issue 提到了这些入口点,但没有给出文件路径。然后阅读 tests/test_004_cursor.py 中现有的游标测试,并添加覆盖连续受影响行数和一个结果集的测试。完成标准是:nextset() 之后,rowcount 能反映每个结果;对于结果集,它的值为 -1。

由索引模型根据 Issue 内容生成。

描述

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.

主要语言
Python
星标
481
派生
62
平均合并
2 天 9 小时
30 天内合并 PR
11

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

microsoft/mssql-python 的其他 Issue

查看 microsoft/mssql-python 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。