Cursor.nextset() does not update rowcount for the next result
维护者通常 2 天内回复
评估
调研方向
从 Cursor_nextset 和 execute() 的实现开始,比较它们各自如何刷新 rowcount;issue 提到了这些入口点,但没有给出文件路径。然后阅读 tests/test_004_cursor.py 中现有的游标测试,并添加覆盖连续受影响行数和一个结果集的测试。完成标准是:nextset() 之后,rowcount 能反映每个结果;对于结果集,它的值为 -1。
由索引模型根据 Issue 内容生成。
描述
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;
-1for a result set, whichfetch*()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
mainat 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
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
microsoft/mssql-python 的其他 Issue
-
triage needed
难度 4/5 3-5 天 新手友好度 48/100
microsoft/mssql-python#862 · 2 条评论 ·
维护者通常 2 天内回复
-
Pooled connection checkout has no timeout: connect() hangs ~16 min on a dead socket可能已有人在做 @jahnvi480 于 5 天前认领。 未关闭area: connectivity-auth bug inADO triage done under development
难度 4/5 3-5 天 新手友好度 48/100
microsoft/mssql-python#854 · 3 条评论 · 已指派 1 人 ·
维护者通常 2 天内回复
-
triage needed
难度 5/5 一周以上 新手友好度 38/100
microsoft/mssql-python#850 · 2 条评论 · 1 个 reaction ·
维护者通常 2 天内回复
-
bulkcopy() & bulkcopy_arrow() fail with Schannel AcquireCredentialsHandleW error 0x8009030D (SEC_E_UNKNOWN_CREDENTIALS)可能已有人在做 @jahnvi480 于 7 天前认领。 未关闭area: bulk-copy bug inADO triage done
难度 4/5 3-5 天 新手友好度 20/100
microsoft/mssql-python#848 · 5 条评论 · 已指派 1 人 ·
维护者通常 2 天内回复
-
macOS: encrypted connections fail after Homebrew moved the `openssl` alias to `openssl@4`可能已有人在做 @bewithgaurav 于 27 天前认领。 未关闭area: packaging-platform bug triage needed
难度 4/5 3-5 天 新手友好度 55/100
microsoft/mssql-python#826 · 2 条评论 · 3 个 reaction · 已指派 1 人 ·
维护者通常 2 天内回复
查看 microsoft/mssql-python 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 67/100
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
letsencrypt/cp-cps#361 ·
-
难度 2/5 1-3 小时 新手友好度 65/100
-
CI: startup_failure because callers grant fewer permissions than ledger-app-workflows@v1 declares可能已有人在做 @maykonmichel 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 76/100
LedgerHQ/app-boilerplate-rust#227 ·
-
难度 2/5 1-3 小时 新手友好度 76/100
linuxmint/mintupdate#1107 ·