【问题标题】:Closed Cursors - SQL Best Practice封闭游标 - SQL 最佳实践
【发布时间】:2025-12-04 09:10:01
【问题描述】:

我在一个独立的大型开发团队工作。我目前正在从事的项目有一个 Oracle DB 团队,该团队开发存储过程和其他与我们的 J2EE Web 层对话的相关组件。

开发中产生的一件事是在未找到结果时关闭游标的概念。

根据我的经验,关闭的游标表示特殊情况;不一定与数据相关的编程错误。在当前上下文中,它表示没有找到数据,当 empty 结果集/游标对我来说更有意义时。

人们从他们的角度有什么想法或经验?从传统的角度来看,这里有任何 Oracle SQL 开发人员可以阐明我应该是错误的吗?

最佳实践?

干杯!

【问题讨论】:

    标签: sql oracle jdbc


    【解决方案1】:

    我和你在一起。返回一个空的结果集对我来说最有意义。

    这完全是关于关注点分离。数据检索是一项服务。而处理 NO_DATA_FOUND 异常属于调用应用程序。

    编辑

    我希望在一个处理引用游标的PL/SQL 过程中找到cursor%NOTFOUND。例如,一个 PAYROLL 例程可能会使用 SALES 子系统中的一个函数,该函数返回一个销售员接受的所有订单的引用光标(在给定的部门,在给定的季度,等等)。

    我希望 PAYROLL 例程循环遍历返回的结果集并检查 cursor%NOTFOUND。如果没有匹配的推销员,我不希望 SALES 函数这样做并返回一个空光标。除了违反 Least Surprise 原则之外,这还意味着检索函数正在做更多的工作(两次打开 ref 游标)或者它正在返回错误的结果

    SQL> create function get_emps(dno number) return sys_refcursor is
      2    rc sys_refcursor;
      3  begin
      4    open rc for select * from emp where deptno = dno;
      5    return rc;
      6  end;
      7  /
    
    Function created.
    
    SQL> var rc refcursor
    SQL>
    SQL> exec :rc := get_emps(10)
    
    PL/SQL procedure successfully completed.
    
    SQL> print rc
    
    EMPNO ENAME      JOB              MGR HIREDATE    SAL COMM DEPTNO
    ----- ---------- --------- ---------- ---------- ---- ---- ------
    7782 BOEHMER     MANAGER         7839 09-06-1981 2450          10
    7839 SCHNEIDER   PRESIDENT            17-11-1981 5000          10
    7934 KISHORE     CLERK           7782 23-01-1982 1300          10
    
    SQL>
    SQL> create or replace function get_emps(dno number) return sys_refcursor is
      2    rc sys_refcursor;
      3    lrow emp%rowtype;
      4  begin
      5    open rc for select * from emp where deptno = dno;
      6    fetch rc into lrow;
      7    if rc%notfound then
      8      close rc;
      9    end if;
     10    return rc;
     11  end;
     12  /
    
    Function created.
    
    SQL> exec :rc := get_emps(15)
    
    PL/SQL procedure successfully completed.
    
    SQL> print rc
    ERROR:
    ORA-24338: statement handle not executed
    
    
    SP2-0625: Error printing variable "rc"
    SQL> exec :rc := get_emps(10)
    
    PL/SQL procedure successfully completed.
    
    SQL> print rc
    
    EMPNO ENAME      JOB              MGR HIREDATE    SAL COMM DEPTNO
    ----- ---------- --------- ---------- ---------- ---- ---- ------
    7839  SCHNEIDER  PRESIDENT            17-11-1981 5000          10
    7934  KISHORE    CLERK           7782 23-01-1982 1300          10
    
    SQL>
    

    【讨论】:

    • 谢谢。你能想出一个合适的例子吗?