我有一个不返回命中的sql语句。例如,'select * from TAB where 1 = 2'
。
我想检查返回的行数,
cursor.execute(query_sql)
rs = cursor.fetchall()
这里我已经异常:“(0,'没有结果集')”
如何预先设置此异常,检查结果集是否为空?
答案 0 :(得分:37)
cursor.rowcount
通常会设置为0.
但是,如果您运行的语句从不返回结果集(例如INSERT
没有RETURNING
或SELECT ... 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
解决方案之一是:
try
和 except
块可让您处理 error
/exceptions
。 finally
块允许您执行代码,而不管 try
和 except
块的结果如何。
因此可以通过使用它来解决所提出的问题。
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
仅在CREATE
,UPDATE
和DELETE
语句中返回:
| 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.