oracle数据库的存储过程中可以用到隐形游标。但是我不太明白为啥可以用 for in loop来完成对数据的处理。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle数据库的存储过程中可以用到隐形游标。但是我不太明白为啥可以用 for in loop来完成对数据的处理。相关的知识,希望对你有一定的参考价值。

这个属性不是显性游标的吗? 难道可以共用 好比这样:
for my-prdinfo-rec in ( select * from productinfo where category =cur-ctgy
)
lopp
dbms-output.put-line(
产品名称: ' || my-prdinfo-rec.productname
|| '产品价格 : '|| my-prdinfo-rec.productprice
||'产品数量:’|| my-prdinfo-rec.quantity
);
end loop;
呵呵…谢谢大家!其实我是不明白是隐式打开的游标是显式游标还是SQL游标??

这是游标的for循环。用游标的for循环,可以简化游标的操作步骤。使用时系统隐式地定义了一个游标名%ROWTYPE类型的记录变量,作为循环的计数器。使用游标的for循环,必须按正常方式先定义游标,然后在块的主体内使用for循环代替显示第打开游标和关闭游标。循环自动地处理查询返回的所有行。当最后一行被取出后,循环会自动终止。它会自动完成下列三步:
1.打开游标
2.取数据
3.关闭游标
参考技术A loop你打错了~

打一个比喻来解释吧

for 100元 in ( 你的银行卡)
loop
用100元买东西;
钱用完了;
end loop;

意思是每次取出来100元,花没了再取,一直到你银行卡里没钱为止

所谓显式游标,就是声明过游标,可以理解为显示出来让别人知道;
至于隐式游标,不需要声明,直接默默的使用就行了
你这个是for循环的隐式游标追问

那 已您的意思 。 隐式游标就有两种了。。 第一种是:for 循环 隐式声明了 游标 打开游标 循环结束就关闭游标。 第二种:就是我们所说的SQL 游标。。 显示游标就如您所说的声明过的游标。 显示给别人知道。 您说我这样理解可以吗??

本回答被提问者采纳

oracle-游标-存储过程-函数-包

一、存储过程
不可以在insert,update,delete中直接使用,可以有return但代表的是退出过程
过程有三种类型:不返回值,可以返回多个值,参数有三种类型,分别如下:
        in:只输入,不返回结果,默认为in
        out:只返回结果,不输入,要想取出输出变量的值必须通过pl/sql块的变量取出
        in  out:可输入,又可返回结果,要想取出输出变量的值必须通过pl/sql块的变量取出
    --语法
    create or replace procedure 名称(a1 in varchar2,a2 out varchar2,a3 in out int)
        as 

        begin

        end;
    --测试in
        create or replace procedure getSex1(p_customerName in varchar2)
        as 
            v_sex varchar2(20);
        begin
            select sex into v_sex from customer where customerName=p_customerName;
            dbms_output.put_line(v_sex);
        end; 
    --测试out
      create or replace procedure getSex2(p_customerName in varchar2,p_sex out varchar2)
        as 
        begin
          select sex into p_sex from customer where customerName like p_customerName;
        exception
          when others then raise_application_error(-20001,‘occur error‘);
        end;
    --测试in out
        create or replace procedure getSex3(p_param1 in out varchar2) 
        as 
        begin
            select sex into p_param1 from customer where customerName=p_param1;
        end;
    --在pl/sql块中执行
        declare
        begin
              getSex1(‘a1‘);
        end;
    
--在pl/sql块中执行
        declare
            p_sex varchar2(20);
        begin
            getSex2(‘a1‘,p_sex);
            dbms_output.put_line(p_sex);
            getSex2(‘a2‘,p_sex);
            dbms_output.put_line(p_sex);
        end;
        
        declare
            p_sex varchar2(20);
        begin
            p_sex:=‘a1‘;
            getSex3(p_sex);
            dbms_output.put_line(p_sex);
            p_sex:=‘a2‘;
            getSex3(p_sex);
            dbms_output.put_line(p_sex);
        end;
二、函数:
        只能返回且必须返回一个结果,可以直接用在insert,update,delele,select中
    可以有多个return;
    语法:
        create or replace function 函数名(p1 varchar2) return varchar2
        as
        begin
        exception
        end;
    实例:根据姓名返回姓别
        create or replace function getSex(p_customerName varchar2) return varchar2
        as
            v_sex customer.sex%type;
        begin
            select sex into v_sex from customer where customerName=p_customerName;
            return v_sex;
        end;
执行函数:
        1、在sql(sqlplus)
            select getSex(customerName),sex from customer;
        2、在pl/sql块中
      declare
                v_sex customer.sex%type;
            begin
                v_sex:=getsex(‘a1‘);
                dbms_output.put_line(v_sex);
            end;

存储过程:
                  1.声明处没有return,可以返回多个值,用输出变量(out,in out)返回
                    return代表退出程序,不返回结果.
                  2.不可以在insert,update,delete,select
                    中直接使用,只能通过exec中用
 函数:
                  1.声明处有return,只可以返回一个值,
                    return代表返回一个值.
                  2.可以在insert,update,delete,select
                    中直接使用.

三、触发器
set serveroutput on;
create or replace trigger teacher_trigger after insert or update or delete on customer for each row 
begin
dbms_output.put_line(‘the table data already has been modified....‘);
end;

四、游标
        declare
                    v_customer customer%rowtype;
                    v_customerName customer.customerName%type;
                    cursor c1(v_customerName varchar2) is select * from customer     where customerName like v_customerName;
              begin
                    v_customerName:=‘&aa‘;
                    open c1(v_customerName);
                    fetch c1 into v_customer;
                    while(c1%found) loop
                        dbms_output.put_line(v_customer.customerName||‘      ‘||v_customer.sex);
                        fetch c1 into v_customer;
                    end loop;
              end;

五、包
包:包中可以有多个方法,包包括包声明与包主体,包声明中声明的方法名,参数名,类型,个数必须与包主体的方法完全一样。
       包声明中声明的变量是全局变量,大家都可以用
       --实现包声明
create or replace package my_p 
as 
    function getReverse(v_name varchar2) return varchar2;
    procedure teacher_modify_column(teacher_id number,column_name varchar2,column_value1 number);
end;

create or replace package body my_p
as
procedure teacher_modify_column(teacher_id number,column_name varchar2,column_value1 number)
      is 
        v_sql varchar2(200);
      begin
        v_sql:=‘update teachers set  ‘||column_name||‘ =  ‘||column_value1||‘   where teachers.teacher_id =  ‘||teacher_id;
        EXECUTE IMMEDIATE v_sql;    
end teacher_modify_column;
 
function getReverse(v_name varchar2) return varchar2
as
v_title varchar2(200);
i int:=1;
j int:=0;
begin
 j:=length(v_name);
 while (j>0) loop
 v_title:= substr(v_name,i,1)||v_title;
 i:=i+1;
 j:=j-1;
 end loop;
return v_title;
end;
end;

      create or replace package MyPackage as
           type c_type is ref cursor;
           function MyReverse(source varchar2) return varchar2;
           procedure splitPage(p_sql varchar2,page int,pageSize int,result out c_type,pageCount out int); 
      end;
       --实现包主体
        create or replace package body MyPackage as
               function MyReverse(source varchar2) return varchar2
               as 
                 i int;
                 j int;
                 result varchar2(2000):=‘‘;
               begin
                 j:=length(source);
                 i:=1;
                 while(i<=j) loop
                   result:=substr(source,i,1)||result;
                   i:=i+1;
                 end loop;
                 return result;
               end;
             // 查询语句           页数                                                 
               procedure splitPage(p_sql varchar2,page int,pageSize int,result out c_type,pageCount out int)
               as 
                 v_sql varchar2(500);
                 startPage int;
                 endPage int;
                 v_rowCount int;
               begin
                 v_sql:=‘select count(*) from (‘||p_sql||‘)‘;
                 dbms_output.put_line(v_sql);
                 execute immediate v_sql into v_rowCount;
                 pageCount:=ceil(v_rowCount/pageSize);
                 if(page=0) then 
                   raise_application_error(-20001,‘申请的页面太小‘);
                 end if;
                 if(page>pageCount) then 
                   raise_application_error(-20001,‘申请的页面太大‘);
                 end if;
                 startPage:=(page-1)*pageSize;
                 endPage:=page*pageSize;
                 v_sql:=‘select * from (‘||p_sql||‘) where rowNum<=‘||to_char(endPage);
                  v_sql:=v_sql||‘ minus ‘; 
                  v_sql:=v_sql||‘select * from (‘||p_sql||‘) where rowNum<=‘||to_char(startPage);
                  dbms_output.put_line(v_sql);
                  open result for v_sql;
              end;
    end;
    --调用包中的方法
        select MyPackage.MyReverse(sex) from customer;
    --在pl/sql块中调用
    declare
      pageCount int;
      c1 mypackage.c_type;
      v_customer customer%rowtype;
    begin
      mypackage.splitPage(‘select * from customer‘,1,2,c1,pageCount);
      dbms_output.put_line(‘总页数是‘||pageCount);
      fetch c1 into v_customer;
      while(c1%found) loop
             dbms_output.put_line(v_customer.customername||‘  ‘||v_customer.sex);
             fetch c1 into v_customer;
      end loop;
      close c1;
      mypackage.splitPage(‘select * from customer‘,2,2,c1,pageCount);
      fetch c1 into v_customer;
      while(c1%found) loop
             dbms_output.put_line(v_customer.customername||‘  ‘||v_customer.sex);
             fetch c1 into v_customer;
      end loop;
      close c1;
      mypackage.splitPage(‘select * from customer‘,3,2,c1,pageCount);
      fetch c1 into v_customer;
      while(c1%found) loop
             dbms_output.put_line(v_customer.customername||‘  ‘||v_customer.sex);
             fetch c1 into v_customer;
      end loop;
      close c1;  
      
      mypackage.splitPage(‘select * from customer‘,4,2,c1,pageCount);
      fetch c1 into v_customer;
      while(c1%found) loop
             dbms_output.put_line(v_customer.customername||‘  ‘||v_customer.sex);
             fetch c1 into v_customer;
      end loop;
      close c1;      
    end;

 

以上是关于oracle数据库的存储过程中可以用到隐形游标。但是我不太明白为啥可以用 for in loop来完成对数据的处理。的主要内容,如果未能解决你的问题,请参考以下文章

oracle存储过程效率问题,处理1500w的数据插入

Oracle --- 存储过程函数包游标触发器

Oracle --- 存储过程函数包游标触发器

Oracle --- 存储过程函数包游标触发器

oracle过程中游标作为输入参数 求解。。。

oracle-游标-存储过程-函数-包