Pl-SQL游标中存储的数据是动态的还是静态的?
Stored data in Pl-SQL cursor is dynamic or static?
声明游标时,它是静态数据集还是声明之后,如果在开始循环之前输入了新数据,它是否会为循环拾取?
声明游标定义了具有名称和关联的 SELECT 语句的游标。声明游标后,您需要打开游标,为游标分配内存,并准备好将SQL 语句返回的行读取到其中。例如:
声明游标
光标 c_customers 是
SELECT id, name, address FROM customers;
打开游标
打开c_customers;
打开后,您可以通过获取游标一次访问一行:
FETCH c_customers INTO c_id, c_name, c_addr;
获取游标后,关闭游标即可:
关闭 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 |
+------+
声明游标时,它是静态数据集还是声明之后,如果在开始循环之前输入了新数据,它是否会为循环拾取?
声明游标定义了具有名称和关联的 SELECT 语句的游标。声明游标后,您需要打开游标,为游标分配内存,并准备好将SQL 语句返回的行读取到其中。例如:
声明游标 光标 c_customers 是 SELECT id, name, address FROM customers;
打开游标 打开c_customers;
打开后,您可以通过获取游标一次访问一行: FETCH c_customers INTO c_id, c_name, c_addr;
获取游标后,关闭游标即可: 关闭 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 |
+------+