我花了很长时间处理这个问题:“没有数据 - 获取、选择或处理零行”。我意识到问题的一部分是不同版本的 MySQL(或者可能是 Django 和 Python)导致不同的行为。我不认为这是特定于 Python 或 Django 的,但不知道。我不知道它是否与设置的某些变量有关,而不是与不同版本中固有的东西有关。
两组版本分别是:
- set1: (MySQL: 5.5.19), (Python: 2.7.1), (Django: 1.3.0)
- set2: (MySQL: 5.0.05), (Python: 2.6.8), (Django: 1.2.4)
我做什么:
在 Python 中(通过 Django):
cursor.execute("select function_1() from dual")
cursor.fetchall()
定义:
- 虚拟查询是指保证返回一行但在代码逻辑中没有任何用途的数据库的任何查询。
- continue_handler_1329 是:为 1329 begin end 声明 continue 处理程序;
在版本 SET1
案例 1a:Python 调用函数_1,其 LAST 查询返回 NULL。我们得到错误。
- 通过在末尾包含虚拟查询(或确保最后一个查询不返回 null)来修复。
- 假设 function_1 没有游标,包括 continue_handler_1329 无效。见下文。
案例 1b:Python 调用 function_1,后者调用 function2。没有 mysql 游标。如果 function2 的 LAST 查询返回 null:Function2 仍然被正确评估并返回正确的值给 function1。
- 无需修复。
- 包括 continue_handler_1329 (在任一函数中)没有效果(它仍然有效)。
案例 1c:Python 调用 function_1,它打开一个调用 function2 的游标(在游标循环内或游标选择本身中)。如果 function2 的 LAST 查询返回 null:这很糟糕。游标立即关闭,并且 function_1 继续运行,就好像游标已被评估一样。没有警告。
- 通过在 function2 末尾包含虚拟查询(或确保其最后一个查询不返回 null)来修复
- 在 function2 中包含 continue_handler_1329 无效。
- 在 function_1 中包含 continue_handler_1329 会导致无限循环。当游标用完行时,它不会在它自己的处理程序中结束,而是在新的处理程序中结束,而不是设置 Done = True。
对 VERSION SET1 的总结:
- 将最后一个虚拟查询添加到从 Python 调用的函数以及可能从游标调用的任何函数。或者以其他方式确保这些函数的最后一个查询永远不会返回 null。continue_handler_1329 不能解决问题,并且会导致带有游标的函数出现问题(除非 continue_handler_1329 在它自己的范围内)。
在版本 SET2
案例 2a:Python 调用 function_1,其中任何查询都返回 NULL。我们得到错误。
- 没有虚拟查询可以解决此问题。
- 通过包含 continue_handler_1329 修复,假设 function_1 没有任何游标(见下文)。或者确保没有查询返回 null。
案例 2b:Python 调用 function_1,后者又调用 function2。没有 mysql 游标。如果 function2s 有任何返回 null 的查询:我们得到错误。
- 没有虚拟查询可以解决此问题。
- 通过在 function2 中包含 continue_handler_1329 来修复(或确保没有查询返回 null)。
- 在 function1 中包含 continue_handler_1329 没有任何效果,除非它有游标(见下文)
案例 2c:Python 调用 function_1,它打开一个调用 function2 的游标(在游标循环内或游标选择本身中)。如果 function2 有任何返回 null 的查询:我们得到错误。
- 没有虚拟查询可以解决此问题。
- 通过在 function2 中包含 continue_handler_1329 来修复(或确保没有查询返回 null)。
- 在 function_1 中包含 continue_handler_1329 会导致无限循环。当游标用完行时,它不会在它自己的处理程序中结束,而是在新的处理程序中结束,而不是设置 Done = True。
SET2 版本的结论
- 将 continue_handler_1329 添加到任何可能具有返回 null 的查询的函数,带有游标的函数除外。这些不应包含任何返回 null 的查询,但声明的游标本身除外。但是,带有游标的函数可能包含一个单独的 begin-end 范围,带有 null-returning-query 和 continue_handler_1329。
总之,它可以在两者中工作:
- 将 continue_handler_1329 添加到所有可能包含返回 null 的查询的函数,并将最后一个虚拟查询添加到从 Python 调用的函数,以及可能从游标调用的任何函数。带有游标的函数可能不包含 continue_handler_1329 也不包含返回 null 的查询,除非它们位于单独的开始-结束范围内。(游标查询本身可能返回 null,这将由游标的 continue 处理程序处理。)。