SQL-游标


数据库游标解决了阻抗不匹配的问题。它充当 SQL 查询结果和处理该结果的语句之间的过滤器。

SQL 中的游标

游标是数据库服务器在对表执行数据操作语言操作(例如 INSERT、UPDATE 和 DELETE 等)时分配的临时内存它用于检索和操作存储在游标中的数据。 SQL 表。

在 MySQL 中,您不能直接在存储过程或函数之外声明游标。游标通常在 MySQL 数据库中的存储过程、函数或 SQL 代码块中声明。

使用游标,我们可以对结果集的每一行执行多个操作,无论是否返回原始数据。

游标的属性

以下是 MySQL 游标的属性 -

  • 只读 -我们无法使用 MySQL 游标更新或修改表中的任何记录。我们可以从表中获取并处理数据。

  • 不可滚动-我们可以从表中单向检索记录,即从第一个记录或最后一个记录。我们无法向后移动或跳转到结果集中的特定位置。

  • 敏感游标-敏感游标直接对数据库中的实际数据进行操作,它不会创建数据的副本。如果其他连接对数据进行任何更改,则可能会影响游标正在使用的数据。

除了不敏感游标之外,还有另一种类型称为不敏感游标。不敏感游标使用数据的临时副本。因此,这些游标对表中所做的更改不敏感(不受影响)。

游标的生命周期

管理这些游标有四个步骤。下图说明了 SQL 游标的生命周期 -

游标生命周期

现在,让我们一一讨论游标生命周期的各个阶段。

声明游标语句

在 MySQL 中,我们可以使用DECLARE语句声明游标并将其与 SELECT 语句关联以从数据库表中检索记录。

但是,与游标关联的此 SELECT 语句不使用 INTO 子句,因为它的目的是获取和处理行而不是为变量赋值。

句法

以下是在 MySQL 数据库中声明游标的语法 -

DECLARE cursor_name CURSOR FOR select_statement;

打开游标语句

在 MySQL 中声明游标后,下一步是使用 OPEN 语句打开游标。它初始化结果集,允许我们从游标中关联的 SELECT 语句中获取并处理行。

句法

以下是在 MySQL 数据库中打开游标的语法 -

OPEN cursor_name;

获取游标语句

然后,我们可以使用 FETCH 语句检索游标指向的当前行,并且每次 FETCH 时,游标都会移动到结果集中的下一行。这使我们能够逐行处理每一行。

句法

以下是在 MySQL 数据库中获取游标的语法 -

FETCH cursor_name INTO variable_list;

关闭游标语句

获取所有行后,我们必须关闭游标以释放与其关联的内存。我们可以使用 CLOSE 语句来做到这一点。

句法

以下是关闭 MySQL 数据库中游标的语法 -

CLOSE cursor_name;

例子

在这个例子中,让我们看看如何管理存储过程中的游标。

假设我们使用CREATE TABLE语句创建了一个名为CUSTOMERS的表,如下所示 -

CREATE TABLE CUSTOMERS (
   ID INT NOT NULL,
   NAME VARCHAR (20) NOT NULL,
   AGE INT NOT NULL,
   ADDRESS CHAR (25),
   SALARY DECIMAL (18, 2),       
   PRIMARY KEY (ID)
);

现在,让我们使用INSERT语句将一些记录插入到CUSTOMERS表中,如下所示 -

INSERT INTO CUSTOMERS VALUES 
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00 ),
(2, 'Khilan', 25, 'Delhi', 1500.00 ),
(3, 'Kaushik', 23, 'Kota', 2000.00 ),
(4, 'Chaitali', 25, 'Mumbai', 6500.00 );

现在,我们将创建一个名为“CUSTOMERS_BACKUP”的备份表来存储客户数据 -

CREATE TABLE CUSTOMERS_BACKUP (
   ID INT NOT NULL,
   NAME VARCHAR (20) NOT NULL,
   PRIMARY KEY (ID)
);

在这里,我们创建一个名为FetchCustomers的存储过程,用于从CUSTOMERS表中获取客户名称,并将它们一一插入到BACKUP表中。我们使用游标来迭代行和处理程序来检测结果集的末尾,确保所有名称都得到处理 -

DELIMITER //
CREATE PROCEDURE FetchCustomers()
BEGIN
   DECLARE done INT DEFAULT FALSE;
   DECLARE customer_id INT;
   DECLARE customer_name VARCHAR(255);
   DECLARE auto_id INT; 

   -- Declare cursor
   DECLARE MY_CURSOR CURSOR FOR
   SELECT id, name FROM CUSTOMERS;

   -- Declare exit handler
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

   -- Open cursor
   OPEN MY_CURSOR;

   -- Fetch and insert rows
   read_loop: LOOP
      FETCH MY_CURSOR INTO customer_id, customer_name;
      IF done = 1 THEN
         LEAVE read_loop;
      END IF;

      -- Insert the fetched data into the backup table
      INSERT INTO customers_backup VALUES (customer_id, customer_name);
		        
      -- Get the last auto-generated ID used in the insertion
      SET auto_id = LAST_INSERT_ID();

   END LOOP;
	
    -- Close cursor
    CLOSE MY_CURSOR;
END //
DELIMITER ;

成功创建过程后,我们可以使用 CALL 语句执行它,如下所示 -

CALL FetchCustomers();

确认

您可以使用 SELECT 语句验证 CUSTOMERS_BACKUP 表的内容,如下所示 -

SELECT * FROM CUSTOMERS_BACKUP;

表的内容是 -

ID 姓名
1 拉梅什
2 基兰
3 考希克
4 柴塔利