SQL 游标
数据库游标解决了阻抗不匹配的问题。它充当了SQL查询结果和处理该结果的语句之间的过滤器。
SQL中的游标
游标 是数据库服务器在执行 D ata M anipulation L anguages诸如INSERT、UPDATE和DELETE等对表进行操作时分配的临时内存。它保存SQL语句返回的多行。您可以使用它检索和操作存储在SQL表中的数据。
例如,当我们对表执行插入操作时,游标会保存要插入的数据。使用游标可以对结果集的每一行执行多个操作,无论是否返回原始数据。
SQL中的游标类型
SQL服务器上有四种游标类型,如下所示−
只向前游标
只向前 (或不可滚动)游标通常被称为SQL服务器中的 默认游标 。它只能以向前的方式滚动结果集。只向前游标不支持滚动功能,即在结果集中向前和向后移动的能力。
这种类型的游标也被称为 消防站 游标,并且仅支持从结果集的开头到结尾获取行。
静态游标
静态 游标是在游标打开时准确显示结果集的游标。打开后,它不会显示任何更新的、删除的或插入的记录。
游标不会反映数据库中对成员身份或结果集所做的任何更改。静态游标不会显示在游标打开后插入到数据库中的新行,即使它们与游标的搜索条件匹配。
注意 - SQL服务器操作(如UPDATE、DELETE和INSERT)不会反映在静态游标中(除非关闭并重新打开游标),而且即使使用操作游标的同一连接进行修改,也不会反射修改。在SQL服务器中,静态游标始终是只读的(它们不能更新)。
键集游标
在SQL服务器中,键集游标提供了静态和动态游标之间的功能,可以检测更改。键集游标具有滚动能力,只能从第一行移动到最后一行,反之亦然。
当打开游标时,行的顺序和成员关系固定,并且唯一标识行的键集将存储在 tempdb 数据库下的一个表中。tempdb数据库是系统数据库之一,用于在SQL服务器中临时存储数据的许多活动中使用。
动态游标
一个 动态 游标是一个静态游标的反向。它在通过游标滚动时反映结果集中行的所有更改。所有用户进行的更新,插入和删除操作都可以通过游标可见。如果通过游标使用API函数或Transact-SQL语句进行更改,则更新或更改将立即可见。
游标的生命周期
以下是SQL Server游标生命周期的图表−
- 光标生命周期的第一阶段是声明它,我们可以使用“Declare”关键字来声明光标,在Declare关键字后面需要指定光标的名称和数据类型,以及SELECT语句。
-
一旦我们声明了光标,我们需要使用“Open”关键字来打开它,以便从结果集中存储和检索数据。
-
在第三阶段,我们使用“Fetch”关键字检索行。
-
一旦我们对检索到的数据进行了所需的操作,我们需要关闭光标。
-
生命周期的最后阶段是“Deallocate”,在这个阶段我们删除光标的定义。
示例
假设我们使用以下“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 (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 );
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Khilan', 25, 'Delhi', 1500.00 );
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
(3, 'kaushik', 23, 'Kota', 2000.00 );
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (4, 'Chaitali', 25, 'Mumbai', 6500.00 );
以下SQL查询在Customers表上创建光标 –
DECLARE MY_CUSR CURSOR FOR SELECT * FROM CUSTOMERS;
输出
以下是上述SQL查询的输出:
Commands completed successfully.
自从光标创建在Customers表上,让我们获取一些记录并释放光标。
OPEN MY_CUSR;
FETCH NEXT FROM MY_CUSR;
CLOSE MY_CUSR;
DEALLOCATE MY_CUSR;
输出
这将生成以下输出 –
+----+----------+-----------+-------------+
| ID | NAME | ADDRESS | SALARY |
+----+----------+-----------+-------------+
| 1 | Ramesh | Ahmedabad | 2000.00 |
+----+----------+-----------+-------------+
示例
让我们在CUSTOMERS表上创建另一个游标,该游标获取并打印数据−
DECLARE @id INT, @name NVARCHAR(50), @sal INT
DECLARE @Counter INT
SET @Counter = 1
DECLARE PrintData CURSOR
FOR
SELECT id, name, salary FROM customers
OPEN PrintData
FETCH NEXT FROM PrintData INTO @id, @name, @sal
WHILE @@FETCH_STATUS = 0
BEGIN
IF @Counter = 1
BEGIN
PRINT 'id' + CHAR(9) + 'name' + CHAR(9) + CHAR(9) + 'sal'
PRINT '--------------------------'
END
PRINT CAST(@id AS NVARCHAR(10)) + CHAR(9) + @name + CHAR(9) + CAST(@sal AS NVARCHAR(10))
SET @Counter = @Counter + 1
FETCH NEXT FROM PrintData INTO @id, @name, @sal
END
CLOSE PrintData
DEALLOCATE PrintData
输出
这将生成以下输出 –
+----+----------+-----------+
| id | name | sal |
+----+----------+-----------+
| 1 | Ramesh | 2000 |
| 2 | Khilan | 1500 |
| 3 | kaushik | 2000 |
| 4 | Chaitali | 6500 |
| 5 | Hardik | 8500 |
| 6 | Komal | 4500 |
| 7 | Muffy | 10000 |
+----+----------+-----------+