【发布时间】:2023-04-01 02:30:01
【问题描述】:
基本上,游标是用于存储特定查询结果的内存区域。我的一个问题是游标是否隐式循环遍历所有记录?假设我编写了如下代码 sn-p:
declare
cursor cur_dum is
select name,class,enroll_id from table_student;
begin
fetch cur_dum into the_name, the_class, the_enroll_id;
update table_log set statement = the_name || '-'||'-'||to_char(the_enroll_id)
where roll_id = the_enroll_id;
close cur_dum;
end;
这段代码sn-p是否会自动循环遍历table_student中的所有记录并在table_log中执行相应的更新?我需要在fetch语句之后添加一个循环吗?如果我在获取期间使用 Bulk collect 语句会有什么不同?
从答案中,我知道明确说明循环是必要的。
我遇到了一段 sn-p 代码,它使用循环作为游标,并在其中使用了 for 循环。以下是 sn-p 代码:
Cursor CurSquirell IS
select Name,a_val,b_val,col_ID from table_temp;
BEGIN
LoopCounter := 0;
commit;
LOOP
FETCH CurSquirell BULK COLLECT INTO my_name,my_a_val,my_b_val,my_col_id LIMIT 1000;
LoopCounter := LoopCounter + 1;
FOR intIndex IN 1 .. my_col_id.COUNT LOOP
counter := counter +1;
BEGIN
select t.tender_val,t.tender_pay, t.page_no, t.loc
into my_tender_val,my_tender_pay,my_page_no , my_loc
from bussiness_trans bt, tender_details t
where t.account_no = bt.account_no
and bt.external_id=my_col_id(intIndex)
and trim(replace(t.tender_pay,'0',' ')) = trim(replace(a_val(intIndex),'0',' '))
and bt.id_type=1;
BEGIN
select pp.lock_id into my__lock_id
from pay_roll pp
where pp.pay_points= my_tender_pay
and bt.id_type=5;
BEGIN
update tab_cross_exchange tce
set tce.cross_b_val = my_b_val(intIndex)
where tce.lock_id = my_lock_id;
..............................sql statements...
...sql statements...
end;
end;
end;
在代码循环中已经使用了一条一条的遍历记录,为什么还要使用for loop?在什么情况下,您需要在游标循环中使用这样的for loop?批量收集是否必须做任何事情来强制使用 For 循环?
【问题讨论】:
-
不,它们不会隐式获取所有行。您需要批量获取或循环,如documented。
-
另外,游标不存储查询结果。它stores information for processing a query。结果将流回给调用者。
-
这么多嵌套的 BEGIN..END 块是代码异味。我不知道您在哪里“遇到了一段 sn-p 代码”,但我不相信这是良好实践的来源。
-
实际上,在尝试修改我的问题以响应您的更新后,我改变了主意。此代码不会编译,也不会运行。它不仅不是良好实践的范例,而且是 shonky code 的典型代表。
-
@APC,我也开始重新格式化它,但失去了住在三层左右的意愿。