📜  DBMS 中的游标——定义、类型、属性、用途

📅  最后修改于: 2022-05-13 01:57:53.194000             🧑  作者: Mango

DBMS 中的游标——定义、类型、属性、用途

数据库管理系统 (DBMS) 支持数据操作语言语句,如插入、更新和删除查询。每个数据库在语法上有所不同,但在上述操作中功能保持不变。在本文中,让我们了解如何使用游标执行插入、更新和删除查询。

光标

每当执行 DML 语句时,都会在系统内存中创建一个临时工作区,称为游标。一个游标可以有不止一行,但在处理方面只考虑了 1 行。游标在 Oracle、SQL Server、MySQL 等各种数据库中都非常有用。它们可以很好地与更新、插入和删除等 DML 语句一起使用。特别是隐式游标与这些操作一起存在。它不时更改值,因此需要在局部变量中分配隐式游标属性值以供进一步使用。在 PL/SQL 中,有两种不同类型的游标可用。

  • 隐式游标
  • 显式游标

显式游标

显式游标由程序员定义,以便在上下文区域拥有更多控制区域。它必须在 PL/SQL 块的声明部分中定义。通常,它在 SELECT 语句中定义,并返回多行作为输出。我们可以遍历数据行并执行所需的操作。

创建显式游标涉及的步骤:

  • 初始化内存的光标声明
CURSOR  IS 
   SELECT  FROM ;
  • 光标打开分配内存
OPEN ; 
  • 光标获取以检索数据
FETCH  INTO 
  • 光标关闭以释放分配的内存
CLOSE ;

例子:

DECLARE 
   empId employees.EMPLOYEEID%type; 
   empName employees.EMPLOYEENAME%type; 
   empCity employees.EMPLOYEECITY%type; 
   CURSOR c_employees is 
      SELECT EMPLOYEEID, EMPLOYEENAME, EMPLOYEECITY FROM employees; 
BEGIN 
   OPEN c_employees; 
   LOOP 
   FETCH c_employees into empId , empName , empCity; 
      EXIT WHEN c_employees %notfound; 
      dbms_output.put_line(empId || ' ' || empName || ' ' || empCity); 
   END LOOP; 
   CLOSE c_employees ; 
END; 
/

输出:

隐式游标

对于 DML 语句,PL/SQL 中可以使用隐式游标,即无需声明游标,即使对于返回 1 行的查询,也可以使用隐式游标。通过游标属性,我们可以跟踪隐式游标的执行信息。

隐式游标的属性:

隐式游标属性提供有关执行 INSERT、UPDATE 和 DELETE 的结果。我们有不同的光标属性,例如“%FOUND”、“%ISOPEN”、“%NOTFOUND”和 %ROWCOUNT。最近执行的 SQL 语句结果将在 Cursor 中可用。最初,游标值将为空。

让我们一一查看关于 DML 语句的不同游标属性。因此,让我们在 oracle 中创建一个名为“employees”的示例表:

CREATE TABLE employees
( EMPLOYEEID number(10) NOT NULL,  
  EMPLOYEENAME varchar2(50) NOT NULL,  
  EMPLOYEECITY varchar2(50)  
); 

在“employees”表中插入记录

INSERT INTO employees (employeeId,employeeName,employeeCity) VALUES (1,'XXX','CHENNAI');
INSERT INTO employees (employeeId,employeeName,employeeCity) VALUES (2,'XYZ','MUMBAI');
INSERT INTO employees (employeeId,employeeName,employeeCity) VALUES (3,'YYY','CALCUTTA');

“员工”表中存在记录

SELECT * FROM employees;

%FOUND 属性

CREATE TABLE tempory_employee  AS SELECT * FROM employees;
DECLARE
  employeeNo NUMBER(4) := 2;
BEGIN
  DELETE FROM tempory_employee WHERE employeeId = employeeNo ;
  IF SQL%FOUND THEN  -- delete succeeded
    INSERT INTO tempory_employee  (employeeId,employeeName,employeeCity)  VALUES (2, 'ZZZ', 'Delhi');
  END IF;
END;
/

现在检查 tempory_employee 表中的详细信息

SELECT * FROM tempory_employee;

输出:

%FOUND 属性和执行更新操作示例

CREATE TABLE tempory_employee1  AS SELECT * FROM employees;
DECLARE
  employeeNo NUMBER(4) := 2;
BEGIN
  DELETE FROM tempory_employee WHERE employeeId = employeeNo ;
  IF SQL%FOUND THEN  -- delete succeeded
     UPDATE employees SET employeeCity = 'Chandigarh' WHERE employeeId = 1;
  END IF;
END;
/

SELECT * FROM 员工的输出:

更新操作时的 %FOUND 属性,然后执行删除操作示例

CREATE TABLE tempory_employee2  AS SELECT * FROM employees;
DECLARE
  employeeNo NUMBER(4) := 2;
BEGIN
  UPDATE tempory_employee2 SET employeeCity = 'Gurgaon' WHERE employeeId = employeeNo;
  IF SQL%FOUND THEN  -- update succeeded
     DELETE FROM tempory_employee2 WHERE employeeId = 1 ;  -- Then delete a specific row
  END IF;
END;
/

输出:

完成以上操作后

%ISOPEN 属性:对于隐式游标,结果始终为 False。原因是 Oracle 在执行 DML 结果后立即关闭。因此结果为 FALSE。

%NOTFOUND 属性:与 %FOUND 正好相反。 %NOTFOUND 与 %FOUND 在逻辑上相反。 %NOTFOUND 对不影响行的 INSERT、UPDATE 或 DELETE 语句产生 TRUE 值。默认情况下,它返回 False。

%ROWCOUNT 属性:受 INSERT、UPDATE 或 DELETE 语句影响的行数由 %ROWCOUNT 给出。当没有行受到影响时,%ROWCOUNT 给出 0 作为结果,否则返回已删除的行数。

CREATE TABLE tempory_employee3  AS SELECT * FROM employees;
DECLARE  employeeNo NUMBER(4) := 2;
BEGIN
  DELETE FROM tempory_employee3 WHERE employeeId = employeeNo ;
  DBMS_OUTPUT.PUT_LINE('Number of employees deleted: ' || TO_CHAR(SQL%ROWCOUNT));
END;

输出:

游标属性的值必须保存在局部变量中,并且这些变量可以在将来的使用中使用。原因是在不同块中执行多个数据库操作时,游标属性值不断变化,因此这是非常需要的。

%NOTFOUND 属性最好只与 DML 语句一起使用,而不是与 SELECT INTO 语句一起使用。