SQL 游标
在SQL中,游标是数据库服务器在执行语句时分配的临时工作站。
它是一个数据库对象,允许我们一次访问一行的数据。当用户想要逐行更新表中的行时,SQL中的这个概念非常有用。
SQL中的游标与其他编程语言的循环技术相同。游标持有的元组集合被称为活动集。
在SQL数据库系统中,用户使用DECLARE语句定义游标,并将SELECT语句作为参数,有助于返回一组行。
在本SQL文章中,我们将学习游标的类型、游标的生命周期、游标的语法和游标的实现。
SQL中的游标类型
以下是结构化查询语言中的两种游标类型:
- 隐式游标
- 显式游标
隐式游标
当系统在SQL查询上执行INSERT、DELETE和UPDATE操作时,会生成和分配这些类型的游标。
这个游标在SQL中也被称为默认游标。
当SELECT查询选择单行时,系统也会创建一个隐式游标。
显式游标
用户使用SELECT查询创建这些类型的游标。
显式游标持有多个记录,但一次只处理一行。它使用指针,在读取一行后移动到另一行。
它基本上用于对临时工作站获得额外的控制。
游标的生命周期
游标的生命周期可以描述为以下五个阶段:
- 声明游标
- 打开游标
- 从游标中获取数据
- 关闭游标连接
- 释放游标
让我们简要讨论每个阶段:
1. 声明游标
首先,我们必须使用以下SQL语法声明游标:
DECLARE Cursor_Name CURSOR FOR Select_Statement;
在这种语法中,我们必须在DECLARE关键字之后指定游标的名称和数据类型。然后,我们必须编写SELECT语句,该语句定义了游标的结果集。
2. 打开游标
这是第二个阶段,用于打开游标以存储从结果集中检索到的数据。我们可以使用以下SQL语法来打开游标:
OPEN Cursor_Name;
3. 获取光标
光标生命周期的第三个阶段是为了在当前活动元祖上执行插入、删除和更新操作而获取行。
以下是从光标中提取数据的语法中使用的六个选项:
i. FIRST: 此选项只允许系统访问光标表中的第一条记录。FIRST选项的语法如下:
FETCH FIRST FROM Cursor_Name;
ii. LAST: 此选项允许系统仅访问游标表中的最后一个记录。LAST选项的语法如下:
FETCH LAST FROM Cursor_Name;
iii. 下一个: 该方法允许系统以从游标表中向前的方向访问数据。这是默认选项。该方法的语法如下:
FETCH NEXT FROM Cursor_Name;
iv. PRIOR(上一个): 此方法允许系统从光标表中向后访问数据。此选项的语法如下:
FETCH PRIOR FROM Cursor_Name;
v. ABSOLUTE n: 通过这种方法,系统可以从光标表中访问第n行的数据。以下是此选项的语法:
FETCH ABSOLUTE n FROM Cursor_Name;
vi. RELATIVE n: 此方法允许系统以增量和减量方式访问数据。此选项的语法如下所示:
FETCH RELATIVE n FROM Cursor_Name;
4. 关闭游标
这是在游标过程中的第四个阶段。当我们完成了对游标的工作后,我们需要在这个阶段关闭游标。我们可以通过使用以下查询在SQL中关闭游标:
CLOSE Cursor_Name;
5. 释放游标
这是游标生命周期的最后一个阶段。在这部分中,我们必须删除游标的定义并释放与游标相关的所有系统资源。
SQL中游标的语法
DECLARE @YourVariables nvarchar(50) //You have to declare all the required variables
DECLARE My_Cursor_Name CURSOR // You have to declare the Name of your Cursor
[LOCAL | GLOBAL] // You have to specify the Scope of your Cursor
[FORWARD_ONLY | SCROLL] // You have to specify the movement direction of your Cursor
[ KEYSET | DYNAMIC |STATIC | FAST_FORWARD] // You have to specify the Basic type of your Cursor
[ SCROLL_LOCKS | OPTIMISTIC |READ_ONLY ] // You have to specify the Locks for your Cursor
OPEN My_Cursor_Name // You have to Open Your Cursor
FETCH NEXT FROM My_Cursor_Name // This line fetches the data from your Cursor
CLOSE My_Cursor_Name // Here, you have to close Your Cursor
DEALLOCATE My_Cursor_Name // Here, you have to deallocate the cursor memory.
基本类型的光标
以下是结构化查询语言中的四种基本类型的光标:
- 静态光标
- 仅向前光标
- 关键字光标
- 动态光标
静态光标
静态光标可以向前和向后移动。这种类型的光标在创建光标时填充结果集。与其他光标相比,它较慢且在内存中使用更多空间。
默认情况下,这些类型的光标是可滚动的。静态光标不允许数据库用户修改和删除数据。
仅向前光标
这种类型的光标只能通过结果集向前访问和更新数据。因此,它是四种光标中最快的光标。
这种光标的主要缺点是不支持向后滚动。
以下是三种’仅向前光标’的类型:
- 仅向前关键字光标,
- 仅向前关键字光标,
- 快速前进光标
动态光标
动态光标与静态光标正好相反。它允许我们在光标打开时执行INSERT、DELETE和UPDATE操作。
它检查结果集中行和值上所做的所有修改。
关键字光标
这种类型的光标从第一行到最后一行,然后从最后一行到第一行访问数据。当用户打开关键字光标时,它会自动创建一个唯一标识整个结果集中每一行的唯一值列表。
SQL中光标的示例
使用以下查询在SQL中创建一个名为Student的表:
CREATE TABLE Student
(
Student_RollNo INT PRIMARY KEY,
Student_Name nvarchar(60) NOT NULL,
Student_Course nvarchar(20) NOT NULL,
Student_Age INTNOT NULL,
Student_Marks INT NOT NULL
) ;
现在,将一些值插入上述学生表中,如下所示:
INSERT INTO Student (Student_RollNo, Student_Name, Student_Course, Student_Age, Student_Marks) VALUES ( 1, Amit, BCA, 19, 88),
( 2, Rahul, MCA, 21, 98),
( 3, Jones, B.tech, 20, 93),
( 4, Riya, BCA, 19, 89),
( 5, Aaniya, BBA, 21, 92),
( 6, Saket, MCA, 19, 95),
( 7, Shobhit, MBA, 20, 90),
( 8, Ishika, BCA, 21, 89),
( 9, Parul, B.tech, 19, 91),
( 10, Yukti, BCA, 20, 96);
我们可以使用以下的SQL SELECT语句来查看学生表的数据:
SELECT * FROM Student;
这个查询显示了输出中Student表的数据:
Student_RollNo | Student_Name | Student_Course | Student_Age | Student_Marks |
---|---|---|---|---|
1 | Amit | BCA | 19 | 88 |
2 | Rahul | MCA | 21 | 98 |
3 | Jones | B.tech | 20 | 93 |
4 | Riya | BCA | 19 | 89 |
5 | Aaniya | BBA | 21 | 92 |
6 | Saket | MCA | 19 | 95 |
7 | Shobhit | MBA | 20 | 90 |
8 | Ishika | BCA | 21 | 89 |
9 | Parul | B.tech | 19 | 91 |
10 | Yukti | BCA | 20 | 96 |
现在,我们将为显示来自学生表的记录创建以下光标:
DECLARE @Student_RollNo INT, @Student_Name NVARCHAR(50), @Student_Course NVARCHAR(50) /*Here, we declare the variables for holding data. */
/* Here, we declare and set counter */
DECLARE @Counter INT
SET @Counter = 1
PRINT '-------- Record of Students --------';
/* Declare the cursor*/
DECLARE Print_Student_Details CURSOR
FOR
SELECT Student_RollNo, Student_Name, Student_Course FROM customer
/* Open the cursor */
OPEN Print_Student_Details
/* Fetch the record from the cursor into the variables. */
FETCH NEXT FROM Print_Student_Details INTO
@Student_RollNo, @Student_Name, @Student_Course
/* LOOP UNTIL RECORDS ARE AVAILABLE. */
WHILE @@FETCH_STATUS = 0
BEGIN
IF @Counter = 1
BEGIN
PRINT 'Student_RollNo' + CHAR(9) + 'Student_Name' + CHAR(9) + CHAR(9) + 'Student_Course'
PRINT '--------------------------'
END
/* This statement prints the current record */
PRINT CAST(@ Student_RollNo AS NVARCHAR(10)) + CHAR(9) + @Student_Name + CHAR(9) + CHAR(9) + @Student_Course
/* This statement increments the counter variable */
SET @Counter = @Counter + 1
/* This statament fetch the next record into the variables. */
FETCH NEXT FROM Print_Student_Details INTO
@Student_RollNo, @Student_Name, @Student_Course
END
/* This statement closes the cursor*/
CLOSE Print_Student_Details
/* This statement deallocates the cursor*/
DEALLOCATE Print_Student_Details
以上光标给出以下输出:
Student_RollNo | Student_Name | Student_Course |
---|---|---|
1 | Amit | BCA |
2 | Rahul | MCA |
3 | Jones | B.tech |
4 | Riya | BCA |
5 | Aaniya | BBA |
6 | Saket | MCA |
7 | Shobhit | MBA |
8 | Ishika | BCA |
9 | Parul | B.tech |
10 | Yukti | BCA |