游标
可以使用游标(cursor)获取查询返回的行。在通过查询将行检索到游标中后,可以一次从游标中取出一行。使用游标时一般需要遵循以下5个步骤:
①声明一些变量,用于保存一行的列值。
②声明游标,它包含一个查询。
③打开游标。
④一次从游标中获取一行,并将列值存储在步骤①声明的变量中。然后对这些变量执行某些操作,例如将它们显示在屏幕上、使用它们进行某种计算。
⑤关闭游标
declare
--step 1: 声明变量
v_product_id PRODUCTS.PRODUCT_ID%type;
v_name PRODUCTS.name%type;
v_price PRODUCTS.PRICE%type;
--step 2: 声明游标
cursor v_product_cursor is
select product_id, name, price
from products
order by product_id;
begin
-- step3: 打开游标
open v_product_cursor;
LOOP
--step4: 从游标中获取行
fetch v_product_cursor
into v_product_id, v_name, v_price;
exit when v_product_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(
'v_product_id = ' || v_product_id || ', v_name = ' || v_name ||
',v_price = ' || v_price
);
end loop;
--step5:关闭游标
close v_product_cursor;
end;
1.5.1 游标与FOR循环
利用FOR循环可以访问游标中的行。当使用FOR循环时,可以不显式地打开和关闭游标——FOR循环会自动执行这些操作。
–游标与FOR循环
declare
cursor v_product_cursor IS
select product_id, name, price
from products
order by product_id;
begin
for v_product in v_product_cursor loop
DBMS_OUTPUT.PUT_LINE(
'v_product_id = ' || v_product.product_id || ', v_name = ' || v_product.name ||
',v_price = ' || v_product.price
);
end loop;
end;
1.5.2 OPEN-FOR语句
也可以对游标使用OPEN-FOR语句,由于可以将游标分配给不同的查询,因此可以更加灵活地处理游标。
–open-for语句
declare
type t_product_cursor is
REF cursor return products%rowtype;
v_product_cursor t_product_cursor;
v_product products%rowtype;
begin
open v_product_cursor for
select * from products where product_id < 5;
loop
fetch v_product_cursor into v_product;
exit when v_product_cursor%notfound;
DBMS_OUTPUT.PUT_LINE(
'v_product_id = ' || v_product.product_id || ', v_name = ' || v_product.name ||
',v_price = ' || v_product.price
);
end loop;
end;
1.5.3 无约束游标
约束游标的返回类型必须与游标运行的查询中的列相匹配。无约束游标没有返回类型,因此可以运行任何查询。
declare
type t_cursor is ref cursor;
v_cursor t_cursor;
v_product products%rowtype;
v_customer customers%rowtype;
begin
open v_cursor for
select * from products where product_id < 5;
loop
fetch v_cursor into v_product;
exit when v_cursor%notfound;
DBMS_OUTPUT.PUT_LINE(
'v_product_id = ' || v_product.product_id || ', v_name = ' || v_product.name ||
',v_price = ' || v_product.price
);
end loop;
open v_cursor for
select * from customers where customer_id < 3;
loop
fetch v_cursor into v_customer;
exit when v_cursor%notfound;
DBMS_OUTPUT.PUT_LINE(
'v_product_id = ' || v_customer.customer_id || ', v_name = ' || v_customer.first_name ||
',v_price = ' || v_customer.last_name
);
end loop;
end;
游标cursor
隐式游标 处理一行数据
显式游标 处理多行数据
declare
cursor c_emp is
select ename,sal from emp;
v_row c_emp%rowtype;
begin
open c_emp; --打开游标
loop
fetch c_emp into v_row;--提取一行数据到变量
exit when c_emp%NOTFOUND;--退出游标
dbms_output.put_line(v_row.ename||'薪资'||v_row.sal);
end loop;
close c_emp;--关闭游标
end;