"不稳定游标"问题
在Firebird中,直到现在包括当前的这个版本(2.5.5),这是一个必须要注意的实现故障,影响更新当WHERE子句中的条件使用了IN(select-expr)及这个表达式的形式为 SELECT FIRST n or SELECT ... ROWS时。
例如:
UPDATE T
SET ...
WHERE ID IN (SELECT FIRST 1 ID FROM T)
被亲切地称为“无限更新循环”,将不断更新行,一遍又一遍,给人的印象是服务器已挂起。
像这样的怪癖可以影响任何数据更改DML操作,大多数情况是当选择条件包括子查询时。一些案例报告排序顺序干扰预期,不涉及子数据查询。它发生是因为,在执行层是建立一个稳定的"目标集合",然后执行数据更新到每个集合成员, DML 语句使用隐式游标执行操作,而不管行当前的符合条件,不知道行以前是否失败或是已经更新。因此,使用一个简单的示例模式 ︰
UPDATE T SET <fields> = <values>
WHERE <conditions>
执行过程如下:
FOR SELECT <values> FROM T
WHERE <conditions>
INTO <tmp_vars> AS CURSOR <cursor>
DO
UPDATE T SET <fields> = <tmp_vars>
WHERE CURRENT OF <cursor>
Firebird的实现没有依据SQL标准,而是要在任何数据被更新前建产稳定集合。Firdbird从V.3开始将向前符合标准。