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 phpmysql_num_rows python 有类似的东西吗? @cwallenpoole len(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 - xrowcount 返回的计数。【参考方案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的用法

Oracle sql%rowcount 返回影响行数;sql server @@RowCount返回影响行数

rowCount()始终返回0

sql%rowcount 返回影响行数