📅  最后修改于: 2020-11-12 01:54:17             🧑  作者: Mango
处理SQL语句时,Oracle将创建一个称为上下文区域的内存区域。光标是指向此上下文区域的指针。它包含处理语句所需的所有信息。在PL / SQL中,上下文区域由Cursor控制。游标包含有关select语句和它所访问的数据行的信息。
游标用于引用程序,一次读取和处理SQL语句返回的行。游标有两种类型:
如果您不对语句使用显式游标,则隐式游标由Oracle在执行SQL语句时自动生成。
默认情况下创建这些语句,以在执行INSERT,UPDATE,DELETE等DML语句时处理语句。
Orcale提供了一些称为“隐式游标”属性的属性,以检查DML操作的状态。其中一些是:%FOUND,%NOTFOUND,%ROWCOUNT和%ISOPEN。
例如:当您执行INSERT,UPDATE,DELETE之类的SQL语句时,游标属性会告诉您是否影响了任何行以及影响了多少行。如果在PL / SQL块中运行SELECT INTO语句,则隐式游标属性可用于查找SELECT语句是否返回了任何行。如果没有选择任何数据,它将返回一个错误。
下表通过其每个属性来区分游标的状态。
Attribute | Description |
---|---|
%FOUND | Its return value is TRUE if DML statements like INSERT, DELETE and UPDATE affect at least one row or more rows or a SELECT INTO statement returned one or more rows. Otherwise it returns FALSE. |
%NOTFOUND | Its return value is TRUE if DML statements like INSERT, DELETE and UPDATE affect no row, or a SELECT INTO statement return no rows. Otherwise it returns FALSE. It is a just opposite of %FOUND. |
%ISOPEN | It always returns FALSE for implicit cursors, because the SQL cursor is automatically closed after executing its associated SQL statements. |
%ROWCOUNT | It returns the number of rows affected by DML statements like INSERT, DELETE, and UPDATE or returned by a SELECT INTO statement. |
创建客户表并有记录:
ID | NAME | AGE | ADDRESS | SALARY |
---|---|---|---|---|
1 | Ramesh | 23 | Allahabad | 20000 |
2 | Suresh | 22 | Kanpur | 22000 |
3 | Mahesh | 24 | Ghaziabad | 24000 |
4 | Chandan | 25 | Noida | 26000 |
5 | Alex | 21 | Paris | 28000 |
6 | Sunita | 20 | Delhi | 30000 |
让我们执行以下程序来更新表并将每个客户的薪水提高5000。在这里,SQL%ROWCOUNT属性用于确定受影响的行数:
创建过程:
DECLARE
total_rows number(2);
BEGIN
UPDATE customers
SET salary = salary + 5000;
IF sql%notfound THEN
dbms_output.put_line('no customers updated');
ELSIF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' customers updated ');
END IF;
END;
/
输出:
现在,如果您检查客户表中的记录,您会发现行已更新。
select * from customers;
ID | NAME | AGE | ADDRESS | SALARY |
---|---|---|---|---|
1 | Ramesh | 23 | Allahabad | 25000 |
2 | Suresh | 22 | Kanpur | 27000 |
3 | Mahesh | 24 | Ghaziabad | 29000 |
4 | Chandan | 25 | Noida | 31000 |
5 | Alex | 21 | Paris | 33000 |
6 | Sunita | 20 | Delhi | 35000 |
显式游标由程序员定义,以获取对上下文区域的更多控制。这些游标应在PL / SQL块的声明部分中定义。它是在SELECT语句上创建的,该语句返回多个行。
以下是创建显式游标的语法:
CURSOR cursor_name IS select_statement;;
使用显式游标时,必须遵循以下步骤。
它使用名称和关联的SELECT语句定义游标。
显式游标清理的语法
CURSOR name IS
SELECT statement;
它用于为游标分配内存,并使其易于将SQL语句返回的行读取到其中。
游标打开的语法:
OPEN cursor_name;
它用于一次访问一行。您可以按如下所示从上述打开的游标中获取行:
游标提取的语法:
FETCH cursor_name INTO variable_list;
它用于释放分配的内存。以下语法用于关闭上面打开的游标。
光标关闭的语法:
Close cursor_name;
程序员定义了显式游标,以获取对上下文区域的更多控制。它在PL / SQL块的声明部分中定义。它是在SELECT语句上创建的,该语句返回多个行。
让我们以一个示例来演示显式游标的用法。在此示例中,我们使用已创建的CUSTOMERS表。
创建客户表并有记录:
ID | NAME | AGE | ADDRESS | SALARY |
---|---|---|---|---|
1 | Ramesh | 23 | Allahabad | 20000 |
2 | Suresh | 22 | Kanpur | 22000 |
3 | Mahesh | 24 | Ghaziabad | 24000 |
4 | Chandan | 25 | Noida | 26000 |
5 | Alex | 21 | Paris | 28000 |
6 | Sunita | 20 | Delhi | 30000 |
创建过程:
执行以下程序以检索客户名称和地址。
DECLARE
c_id customers.id%type;
c_name customers.name%type;
c_addr customers.address%type;
CURSOR c_customers is
SELECT id, name, address FROM customers;
BEGIN
OPEN c_customers;
LOOP
FETCH c_customers into c_id, c_name, c_addr;
EXIT WHEN c_customers%notfound;
dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);
END LOOP;
CLOSE c_customers;
END;
/
输出: