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

时间:2013-05-15 09:26:39

标签: python resultset python-db-api

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

我想检查返回的行数,

cursor.execute(query_sql)

rs = cursor.fetchall()

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

如何预先设置此异常,检查结果集是否为空?

8 个答案:

答案 0 :(得分:37)

cursor.rowcount通常会设置为0.

但是,如果您运行的语句从不返回结果集(例如INSERT没有RETURNINGSELECT ... INTO),那么你不需要打{{1​​}};这些陈述不会有结果集。调用.fetchall()足以运行该语句。


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

  

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

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

答案 1 :(得分:12)

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

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

答案 2 :(得分:6)

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

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

  # handle submit button
def submit(self, event):
    file = open(filename.GetValue(), 'r')
    contents.SetValue(file.read())
    file.close()

def createForm(self):

    # establish the wxPython App 
    app = wx.App()

    # establish the wxPython frame
    win = wx.Frame(None,title="Closes Neighbor", size = (610,535))

    # define the screen widgets

    # text controls
    filename = wx.TextCtrl(win, pos = (100, 50), size = (210, 25))
    latitude = wx.TextCtrl(win, pos = (100, 80), size = (210, 25))
    longitude = wx.TextCtrl(win, pos = (100, 110), size = (210, 25))
    description = wx.TextCtrl(win, pos = (100, 140), size = (210, 25))
    answer = wx.TextCtrl(win, pos = (100, 250), size = (400, 50),
                         style=wx.TE_MULTILINE | wx.HSCROLL)
    answer.SetEditable(False)
    messages = wx.TextCtrl(win, pos = (100, 350), size = (400, 50),
                         style=wx.TE_MULTILINE | wx.HSCROLL)
    messages.SetEditable(False)

    # static labels
    lblTitle = wx.StaticText (win, pos = (200, 25), size = (210,25),
                                label = "Closest Neighbor", style = wx.ALIGN_CENTER)
    lblFilename = wx.StaticText (win, pos = (10, 50), size = (210,25),
                                label = "Filename:")
    lblLatitude = wx.StaticText (win, pos = (10, 80), size = (210,25),
                                label = "Latitude:")
    lblLongitude = wx.StaticText (win, pos = (10, 110), size = (210,25),
                                label = "Longitude:")
    lblDescription = wx.StaticText (win, pos = (10, 140), size = (210,25),
                                label = "Description:")
    lblAnswer = wx.StaticText (win, pos = (10, 250), size = (210,25),
                                label = "Answer:")
    lblMessages = wx.StaticText (win, pos = (10, 350), size = (210,25),
                                label = "Messages:")

    # buttons
    submitButton = wx.Button(win, label='Find the Closest Point',
                           pos = (100, 180), size = (180, 25))
    submitButton.Bind(wx.EVT_BUTTON, self.submit)

    # get the ball roling
    win.Show()
    app.MainLoop()

答案 3 :(得分:4)

Notice: This is for MySQLdb module in Python.

For a SELECT statement, there shouldn't be an exception for an empty recordset. Just an empty list ([]) for cursor.fetchall() and None for cursor.fetchone().

For any other statement, e.g. INSERT or UPDATE, that doesn't return a recordset, you can neither call fetchall() nor fetchone() on the cursor. Otherwise, an exception will be raised.

There's one way to distinguish between the above two types of cursors:

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

答案 4 :(得分:2)

当我需要进行多个 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/exceptionsfinally 块允许您执行代码,而不管 tryexcept 块的结果如何。 因此可以通过使用它来解决所提出的问题。

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

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

答案 5 :(得分:0)

if you're connecting to a postgres database, the following works:

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

答案 6 :(得分: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")

谢谢:)

答案 7 :(得分:0)

作为参考,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.