pyodbc rowcount 只返回 -1
Posted
技术标签:
【中文标题】pyodbc rowcount 只返回 -1【英文标题】:pyodbc rowcount only returns -1 【发布时间】:2022-01-23 19:30:37 【问题描述】:行计数如何工作。我正在使用 pyodbc,它总是返回 -1。
return_query = conn.query_db_param(query, q_params)
print(return_query.rowcount)
def query_db_param(self, query, params):
self.cursor.execute(query,params)
print(self.cursor.rowcount)
【问题讨论】:
cursor.rowcount always -1 in sqlite3 in python3k的可能重复 【参考方案1】:rowcount
指的是最后一次操作影响的行数。所以,如果你执行insert
并且只插入一行,那么它将返回 1。如果你更新 200 行,那么它将返回 200。另一方面,如果你 SELECT
,最后一个操作不会真正影响rows,它是一个结果集。在这种情况下,0
会在语法上不正确,因此接口会返回 -1
。
对于执行设置变量或使用创建/更改命令等操作的操作,它还将返回 -1
。
【讨论】:
谢谢,我认为 rowcount 是查询返回的行数。在 Coldfusion 他们有 queryname.RecordCount php 有 mysql_num_rows python 有类似的东西吗? @cwallenpoolelen(cursor.fetchall())
离你最近。无论如何,这就是 MySQL 在幕后所做的。
另一方面,如果你选择,最后一个操作不会真正影响行,它是一个结果集。在这种情况下,0 将在语法上不正确,因此接口返回 -1。 这是不正确的,抱歉。许多数据库实现会将行数设置为选择的行数。如果无法预先确定该数字,则仅将其设置为 -1;例如SQLite 引擎在返回所有行之前无法告诉您选择了多少行。 pyodbc 文档explicitly covers this case.
@user3525290: rowcount 是 SELECT 查询返回的行数。但并不是所有的数据库引擎都能预先知道这个数字(它们在扫描受影响的表和索引时会找到行,因此只有在所有行都生成后才能知道最终计数)。 Python DB-API 2.0 规范allows the rowcount to be set to -1 in that case.
另一个细微差别:对于UPDATE
,一些数据库只会报告受影响的行数,而不是匹配的行数。当更新的条件匹配 n 行时,可能会发生这种情况,但在这些行中,实际上只有 n - x 会更改(当前行内容与更新不同) ,所以 n - x 是 rowcount
返回的计数。【参考方案2】:
您正在连接的数据库无法为您的查询提供该编号。许多数据库引擎在您获取结果时生成行,扫描它们的内部表和索引数据结构以查找下一个匹配结果。在您获取所有行之前,引擎无法知道最终计数。
当行数未知时,Python DB-API 2.0 specification for Cursor.rowcount
表示在这种情况下该数字必须设置为 -1
:
属性为
-1
,以防[...]接口无法确定最后一次操作的行数。
pyodbc Cursor.rowcount
documentation 符合这个要求:
最后一条 SQL 语句修改的行数。
如果没有执行 SQL 或行数未知,则为 -1。请注意,出于性能原因,数据库在 SQL 选择语句之后立即报告 -1 的情况并不少见。 (在将第一条记录返回给应用程序之前,可能不知道确切的数字。)
pyodbc 并不孤单,另一个易于链接的示例是 Python 标准库 sqlite3
模块;这是Cursor.rowcount
documentation 状态:
根据 Python DB API 规范的要求,rowcount 属性“如果没有在游标上执行
executeXX()
或接口无法确定最后一次操作的行数,则为 -1”。这包括SELECT
语句,因为在获取所有行之前,我们无法确定查询产生的行数。
请注意,对于数据库实现的子集,可以在获取 一些 行后更新行计数值。您必须检查您正在连接的特定数据库文档,以查看该实现是否可以执行此操作,或者行数是否必须保持在 -1。当然,您可以随时进行实验。
您可以先执行COUNT()
选择,或者,如果预计结果集不会太大,则使用cursor.fetchall()
并在结果列表中使用len()
。
【讨论】:
【参考方案3】:如果您使用的是microsoft sql server,并且想要获取之前select语句中返回的行数,则只需执行select @@rowcount
即可。
例如:
cursor.execute("select @@rowcount")
rowcount = cursor.fetchall()[0][0]
【讨论】:
以上是关于pyodbc rowcount 只返回 -1的主要内容,如果未能解决你的问题,请参考以下文章
SqlServer---RowCount 和 @@RowCount的用法和区别
SQL Server中Rowcount与@@Rowcount的用法
SQL Server中Rowcount与@@Rowcount的用法