我正在尝试从11g Oracle表中返回结果集,在收到设置后我需要将所有获取的行设置为更新。
下面的脚本一次只返回一行,我无法让更新按照我喜欢的方式工作。一些基本的解释将是高度关注的。
也许使用rowtype也是一个坏主意?
CREATE OR REPLACE PROCEDURE OWNER_EXT.X_GETEXTERNALACCOUNTREF(result out X_externalaccountref%rowtype)
IS
cur SYS_REFCURSOR;
BEGIN
open cur for select * from X_externalaccountref WHERE externalstatus IS NULL;
LOOP
FETCH cur INTO result;
update X_externalaccountref set externalstatus = 1, externalchangedate = SYSDATE() where X_id = result.X_id;
EXIT WHEN cur%NOTFOUND;
END LOOP;
close cur;
END;
/
答案 0 :(得分:1)
为什么你只返回一条记录: 循环遍历记录集,一次获取一条记录,每次将此记录分配给输出变量。因此,只有您的最后一条记录将存储在输出变量中。
您要做的是返回记录集。为此,您可以使用pl / sql表。要轻松地将一个集合提取到一个表格中,您可以使用批量收集(a link - 但谷歌会发现您更多)。您可以使用rowtype作为表的类型,也可以使用您自己编写的类型。您可以使用包变量来声明类型,或在数据库模式中定义类型。如果你使用rowtype,那一点也不错。如果您的表格应该更改,那么rowtype也会反映这一点,如果您手动声明自己类型中的每一列,则可以省去拖拽代码以添加或删除列的麻烦。
例如:
function hand_out_money
return pck_emp.t_tab_emp
is
tab_emp pck_emp.t_tab_emp;
begin
select *
bulk collect into tab_emp
from emp
where deptno = 20;
update emp
set comm = comm + 10
where deptno = 20;
return tab_emp;
end;
为了能够使用它,请在package_spec中声明t_tab_emp。这样,您可以从调用此代码的位置引用返回的类型。只需将type t_tab_emp is table of emp%rowtype;
放在那里 - 就像我在包pck_emp中所做的那样。
您的主叫代码可以是:
declare
tab_result pck.t_tab_emp;
begin
tab_result := hand_out_money;
end;
进行更新: 如果将所有记录提取到plsql表中,则可以执行单个更新语句:
update X_externalaccountref
set externalstatus = 1, externalchangedate = SYSDATE
where externalstatus IS NULL;
:如果你只返回这个变量,你可以使用一个函数,这对于一个getter是有意义的。
:我通常不喜欢名为'getxxx'的函数或程序然后执行DML。更恰当的是调用你的过程'activate_external_accounts',然后返回记录集。请注意,如果您在更新之前进行批量选择,则不会更新externalstatus和externalchangedate!因此,您不会返回结果集,而是更新前设置。
答案 1 :(得分:1)
update X_externalaccountref
set externalstatus = 1
, externalchangedate = SYSDATE
where externalstatus is null;
为什么不呢?