Pl-SQL游标中存储的数据是动态的还是静态的?

Stored data in Pl-SQL cursor is dynamic or static?

声明游标时,它是静态数据集还是声明之后,如果在开始循环之前输入了新数据,它是否会为循环拾取?

声明游标定义了具有名称和关联的 SELECT 语句的游标。声明游标后,您需要打开游标,为游标分配内存,并准备好将SQL 语句返回的行读取到其中。例如:

  1. 声明游标 光标 c_customers 是 SELECT id, name, address FROM customers;

  2. 打开游标 打开c_customers;

  3. 打开后,您可以通过获取游标一次访问一行: FETCH c_customers INTO c_id, c_name, c_addr;

  4. 获取游标后,关闭游标即可: 关闭 c_customers;

所以不会被循环拾取。

Oracle 提供Statement-Level Read Consistency,它保证单个查询返回的数据在查询开始时是提交的和一致的。

有一些细节与事务隔离级别、闪回查询和执行查询的用户定义函数有关,但通常一旦查询开始(在程序方面,当游标打开时),其结果将是与当时一样真实,无论任何数据更改(提交或其他)。

我在 mysql 中尝试过,在 mysql 中它正在获取数据。
我创建了一个新的 table 并编写了一个程序。此过程在新创建的空 table、打开的游标和 record_cnt 变量中插入两条记录 select FOUND_ROWS()
FOUND_ROWS() 给出游标获取的行数。在 Oracle 中它是 cursor_name%ROWCOUNT
在 Oracle 中,肯定会有其他语法差异,但我认为行为是相同的,并且如果在打开游标之前插入并提交值,游标将可见这些值。

CREATE TABLE my_tab(id int);

DELIMITER $$
CREATE PROCEDURE cursor_test(OUT record_cnt INT)
 BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE cur1 CURSOR FOR SELECT * FROM my_tab;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
  INSERT INTO my_tab VALUES(1),(2);
  COMMIT;
  OPEN cur1;
  SELECT FOUND_ROWS() INTO record_cnt;
  CLOSE cur1;
END$$
DELIMITER ;

CALL cursor_test(@rec);

select @rec;
+------+
| @rec |
+------+
|    2 |
+------+