Postgresql 游标在plpgsql函数中创建的表中检索已删除的行

Postgresql 游标在plpgsql函数中创建的表中检索已删除的行,postgresql,cursor,plpgsql,Postgresql,Cursor,Plpgsql,在plpgsql函数中,我创建了一个表,并使用游标访问它的行。在第一行中,我删除了后面的一行,但令人惊讶的是(至少对我来说)光标获取了它。在同一个函数中重复时,它的工作方式与我预期的一样 但是,如果表预先存在并且不是在函数中创建的,则永远不会获取已删除的行 我错过了什么 DECLARE curs1 refcursor; rec record; BEGIN CREATE TABLE test as select generate_series(1,5,1) test_id; OPEN curs

在plpgsql函数中,我创建了一个表,并使用游标访问它的行。在第一行中,我删除了后面的一行,但令人惊讶的是(至少对我来说)光标获取了它。在同一个函数中重复时,它的工作方式与我预期的一样

但是,如果表预先存在并且不是在函数中创建的,则永远不会获取已删除的行

我错过了什么

DECLARE
curs1 refcursor;
rec record;

BEGIN
CREATE TABLE test as select generate_series(1,5,1) test_id;

OPEN curs1 FOR SELECT * FROM test ORDER BY test_id; 
  LOOP
    FETCH curs1 INTO rec;
    EXIT WHEN NOT FOUND;
    RAISE NOTICE 'ROW:%',rec.test_id;
    IF rec.test_id=1 THEN
      DELETE FROM TEST WHERE test_id=3;
    END IF;
  END LOOP;
CLOSE curs1;

RAISE NOTICE 'AGAIN';
--just repeating without deleting

OPEN curs1 FOR SELECT * FROM test ORDER BY test_id; 
  LOOP
    FETCH curs1 INTO rec;
    EXIT WHEN NOT FOUND;
    RAISE NOTICE 'ROW:%',rec.test_id;
  END LOOP;
CLOSE curs1;
输出为:

NOTICE:  ROW:1
NOTICE:  ROW:2
NOTICE:  ROW:3
NOTICE:  ROW:4
NOTICE:  ROW:5
NOTICE:  AGAIN
NOTICE:  ROW:1
NOTICE:  ROW:2
NOTICE:  ROW:4
NOTICE:  ROW:5

原因是Postgres游标在默认情况下是“不敏感的”

SQL标准说,它取决于实现 游标对基础数据的并发更新非常敏感 默认在PostgreSQL中,游标默认不敏感,可以 通过为更新指定
使敏感。其他产品可能会有不同的工作方式

我的

因此,请尝试使用
FOR UPDATE
子句:

DO
$$
DECLARE
   curs1 refcursor;
   rec record;
BEGIN
   CREATE TABLE test AS SELECT generate_series(1,5) test_id;

   OPEN curs1 FOR SELECT * FROM test ORDER BY test_id FOR UPDATE; 
   DELETE FROM test WHERE test_id = 3;
   LOOP
      FETCH curs1 INTO rec;
      EXIT WHEN NOT FOUND;
      RAISE NOTICE 'ROW:%',rec.test_id;
   END LOOP;
   CLOSE curs1;
END
$$
第3行不再可见

NOTICE:  ROW:1
NOTICE:  ROW:2
NOTICE:  ROW:4
NOTICE:  ROW:5