65

我有一个不返回任何命中的 sql 语句。例如,'select * from TAB where 1 = 2'

我想检查返回了多少行,

cursor.execute(query_sql)

rs = cursor.fetchall()

在这里我已经得到异常:“(0,'没有结果集')”

我怎样才能防止这个异常,检查结果集是否为空?

4

9 回答 9

69

cursor.rowcount通常会设置为 0。

但是,如果您正在运行一个永远不会返回结果集的语句(例如INSERT没有RETURNING, 或SELECT ... INTO),那么您不需要调用.fetchall(); 此类语句不会有结果集。调用.execute()足以运行语句。


请注意,-1如果数据库适配器无法确定确切的受影响计数,则还允许数据库适配器将行计数设置为。请参阅PEP 249Cursor.rowcount规范

该属性是-1在没有.execute*()对游标执行或最后一次操作的行数无法由接口确定的情况下。

图书馆sqlite3容易这样做。COUNT()在所有这些情况下,如果您必须预先知道受影响的行数,请先在同一事务中执行选择。

于 2013-05-15T09:28:35.897 回答
27

无论我尝试什么解决方案,我都遇到了 rowcount 总是返回 -1 的问题。

我发现以下是检查空结果的好替代品。

c.execute("SELECT * FROM users WHERE id=?", (id_num,))
row = c.fetchone()
if row == None:
   print("There are no results for this query")
于 2018-03-30T19:50:08.963 回答
24

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

rows_count = cursor.execute(query_sql)
if rows_count > 0:
     rs = cursor.fetchall()
else:
     // handle empty result set
于 2013-05-15T13:18:21.440 回答
6

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

对于一个SELECT语句,空记录集不应该有例外。只是一个空列表 ( []) forcursor.fetchall()Nonefor cursor.fetchone()

对于不返回记录集的任何其他语句,例如INSERTor ,您既不能调用也不能在游标上。否则,将引发异常。UPDATEfetchall()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
于 2016-02-03T03:52:20.147 回答
3

当我需要进行多个 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

解决方案之一是:

tryandexcept块让你处理error/ 。exceptionsfinally块允许您执行代码,而不管tryandexcept块的结果如何。所以提出的问题可以通过使用它来解决。

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 ***********************

上面的示例仅提供了一个简单的用途,作为可以帮助您解决问题的想法。当然,你也应该注意其他的错误,比如查询的正确性等等。

于 2021-02-01T23:49:40.663 回答
0

如果您要连接到 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
于 2017-04-10T01:00:31.020 回答
0

你可以这样做:

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")

谢谢 :)

于 2017-10-04T10:53:21.920 回答
0

作为参考,cursor.rowcount将只返回CREATE,UPDATEDELETE语句:

 |  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.
于 2020-06-10T12:25:18.090 回答
0

我的功能对我有好处

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()
于 2021-12-27T16:12:11.833 回答