Oracle中隐式和显式游标之间的区别

PPS*_*ein 2 sql oracle plsql

我想知道这两个陈述之间的区别.这个比那个好吗 ?

DECLARE
    myvar varchar2(50);
BEGIN
    SELECT fieldone into myvar FROM tbl_one WHERE id = 1;
END;
Run Code Online (Sandbox Code Playgroud)

DECLARE
    CURSOR L1 IS
    SELECT fieldone FROM tbl_one WHERE id = 1;
BEGIN
    OPEN L1;
    FETCH L1 INTO myvar;
    CLOSE L1;
END;
Run Code Online (Sandbox Code Playgroud)

Gar*_*ers 11

如果没有返回行或者返回多行,则第一个将引发异常.如果您不处理异常,则会将其抛回调用例程或客户端软件.这称为隐式游标.

第二个会默默地失败.如果没有返回任何行,那么myvar将具有一个空值(尽管如果你认为它是未定义的,它更可取).如果将返回多行,则仅存储第一行中的值.没有ORDER BY,哪个值是'first'是未定义的.这称为显式游标.

所以问题是,如果没有找到数据或行数太多,你想要发生什么.如果您确定永远不会发生,或者不知道如何处理它,那么请选择选项1.

如果您确实只希望找到无数据的情况,那么请使用隐式游标但添加异常处理程序.

如果您希望有多行,则可以使用带有异常处理程序的隐式游标,或者如果您确实需要处理多行,则可以使用BULK SELECT或CURSOR LOOP.

如果要选择多个字段,定义显式游标并使用%TYPE声明来声明所有必需的变量会很有用.

从绩效的角度来看,没有区别.从维护的角度来看,有些人喜欢他们的SELECT'in-line'和他们的代码(所以更喜欢隐式游标).我更喜欢我的'偏离',特别是如果有一个大的列列表,所以我喜欢明确的游标.


Ada*_*sch 5

我不知道你问的是什么问题,但是这里有.

你应该像这样使用PL/SQL吗?

declare
  myvar varchar2(50);
begin
  select fieldone 
    into myvar
    from tbl_one;
end;
/
Run Code Online (Sandbox Code Playgroud)

好吧,当且仅当您知道select语句可以返回一行时,您可以; 或者,您需要对TOO_MANY_ROWS和NO_DATA_FOUND异常进行错误处理,否则将引发异常.


当使用显式游标(即CURSOR关键字)时,有几个操作来控制它的行为.

declare
  myvar varchar2(50);
  CURSOR L1 IS
  SELECT fieldone FROM tbl_one ;
begin
  OPEN L1;
  FETCH L1 into myvar;
  CLOSE L1;
end;
/
Run Code Online (Sandbox Code Playgroud)

CURSOR L1...是游标的声明.它只不过是绑定静态SQL语句,并且所有PL/SQL引擎都检查SQL在语法和上下文中是否有效 - 是否存在缺少的子句?这个用户可以从这个表中选择吗?

OPEN L1打开光标,确定结果将反映的系统历史记录中的确切点.针对该游标的任何后续FETCH将反映该精确点的数据.

FETCH L1...实际上,将结果集的第一行/下一行(无论它是什么)返回到您指定的变量中.它可以是声明的记录,也可以是变量列表.

CLOSE L1...释放光标打开的所有资源; 例如,影响记录的插入/更新/删除操作会生成用户会话具有已声明的读取兴趣的撤消操作,因此在关闭游标之前无法释放或重用撤消操作.