【问题标题】:Return basic result set from Oracle 11g从 Oracle 11g 返回基本结果集
【发布时间】:2011-12-30 11:17:46
【问题描述】:

我正在尝试从 11g Oracle 表中返回结果集,在收到返回的结果集后,我需要将所有获取的行设置为已更新。

下面的脚本一次只返回一行,我不能真正让更新按我喜欢的方式工作。一些基本的解释将非常受欢迎。

也许使用行类型也是一个坏主意?

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;
/

【问题讨论】:

    标签: oracle oracle11g


    【解决方案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 将不会更新!所以你得到的不是结果集,而是一个更新前的集。

    【讨论】:

    • 完美!来自 SQL Server 的一切都有些扭曲。谢谢。
    【解决方案2】:
    update X_externalaccountref 
    set  externalstatus = 1
    , externalchangedate = SYSDATE
    where externalstatus  is null;
    

    为什么不呢?

    【讨论】:

    • 嗯,基本上是因为我只得到最后一行作为响应。但感谢@Tom,我现在明白了。
    猜你喜欢
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多