如何检查结果集是否为空?

我有一个 sql 语句,它不返回任何命中。

我想检查返回了多少行,

cursor.execute(query_sql)


rs = cursor.fetchall()

这里我已经得到了例外: “(0,‘ No result set’)”

如何防止此异常,检查结果集是否为空?

185063 次浏览

通常将 cursor.rowcount设置为0。

但是,如果您运行的语句将 永远不会返回一个结果集(比如没有 RETURNINGSELECT ... INTOINSERT) ,那么您不需要调用 .fetchall(); 对于这样的语句不会有一个结果集。调用 .execute()就足以运行语句。


注意,如果数据库适配器不能确定确切的受影响计数,那么也允许数据库适配器将行数设置为 -1。见 PEP 249 Cursor.rowcount规范:

如果没有对游标执行 .execute*(),或者接口无法确定最后一次操作的行数,则该属性为 -1

sqlite3倾向于这样做。在所有这些情况下,如果您必须事先知道受影响的行数,那么首先在同一个事务中执行 COUNT() select。

如果结果集为空,MySQLdb 将不会引发异常。此外,cursor.execute ()函数将返回一个长值,即所取结果集中的行数。因此,如果要检查空结果,可以将代码重写为

rows_count = cursor.execute(query_sql)
if rows_count > 0:
rs = cursor.fetchall()
else:
// handle empty result set

注意: 这是 Python 中的 MySQLdb 模块。

对于 SELECT语句,对于空记录集不应该有异常。只有 cursor.fetchall()的空列表([])和 cursor.fetchone()None

对于不返回记录集的任何其他语句,例如 INSERTUPDATE,您既不能对游标调用 fetchall()也不能调用 fetchone()。否则,将引发异常。

有一种方法可以区分上述两种类型的游标:

def yield_data(cursor):
while True:
if cursor.description is None:
# No recordset for INSERT, UPDATE, CREATE, etc
pass
else:
# Recordset for SELECT, yield data
yield cursor.fetchall()
# Or yield column names with
# yield [col[0] for col in cursor.description]


# Go to the next recordset
if not cursor.nextset():
# End of recordsets
return

如果你连接到 postgres 数据库,下面的工作:

result = cursor.execute(query)


if result.returns_rows:
# we got rows!
return [{k:v for k,v in zip(result.keys(), r)} for r in result.rows]
else:
return None

你可以这样做:

count = 0
cnxn = pyodbc.connect("Driver={SQL Server Native Client 11.0};"
"Server=serverName;"
"Trusted_Connection=yes;")
cursor = cnxn.cursor()
cursor.execute(SQL query)
for row in cursor:
count = 1
if true condition:
print("True")
else:
print("False")
if count == 0:
print("No Result")

谢谢:)

无论我尝试什么解决方案,行计数总是返回 -1,这是一个问题。

我找到了一个很好的替代方法来检查空结果。

c.execute("SELECT * FROM users WHERE id=?", (id_num,))
row = c.fetchone()
if row == None:
print("There are no results for this query")

作为参考,cursor.rowcount只返回 CREATEUPDATEDELETE语句:

 |  rowcount
|      This read-only attribute specifies the number of rows the last DML statement
|      (INSERT, UPDATE, DELETE) affected.  This is set to -1 for SELECT statements.

当我需要进行多个 sql 查询时,也遇到了类似的问题。 问题是有些查询没有返回结果,我想打印这个结果。这是个错误。如前所述,有几种解决方案。

if cursor.description is None:
# No recordset for INSERT, UPDATE, CREATE, etc
pass
else:
# Recordset for SELECT

还有:

exist = cursor.fetchone()
if exist is None:
... # does not exist
else:
... # exists

解决方案之一是:

tryexcept块允许您处理 error/exceptions。无论 tryexcept块的结果如何,finally块都允许您执行代码。 因此,本文提出的问题可以用它来解决。

s = """ set current query acceleration = enable;
set current GET_ACCEL_ARCHIVE = yes;
SELECT * FROM TABLE_NAME;"""


query_sqls = [i.strip() + ";" for i in filter(None, s.split(';'))]
for sql in query_sqls:
print(f"Executing SQL statements ====> {sql} <=====")
cursor.execute(sql)
print(f"SQL ====> {sql} <===== was executed successfully")
try:
print("\n****************** RESULT ***********************")
for result in cursor.fetchall():
print(result)
print("****************** END RESULT ***********************\n")
except Exception as e:
print(f"SQL: ====> {sql} <==== doesn't have output!\n")
# print(str(e))

产出:

Executing SQL statements ====> set current query acceleration = enable; <=====
SQL: ====> set current query acceleration = enable; <==== doesn't have output!


Executing SQL statements ====> set current GET_ACCEL_ARCHIVE = yes; <=====
SQL: ====> set current GET_ACCEL_ARCHIVE = yes; <==== doesn't have output!


Executing SQL statements ====> SELECT * FROM TABLE_NAME; <=====


****************** RESULT ***********************


----------   DATA   ----------


****************** END RESULT ***********************

上面的例子只是提供了一个可以帮助解决问题的想法的简单用法。当然,您还应该注意其他错误,如查询的正确性等。

我的功能对我有好处

option = cursor.execute("SELECT value FROM options WHERE key = '{}'".format(key))
if option.fetchone() is not None:
return cursor.execute("SELECT value FROM options WHERE key = '{}'".format(key)).fetchone()