zoukankan      html  css  js  c++  java
  • oracle存储过程游标的使用(批号分摊)

    create or replace procedure pf_st2(in_billno in integer) is

    begin

      delete from kk_bal;

      commit;

      declare

       --类型定义

       cursor cur_orderdt is select goodsid,entid,billno,billsn,basenum,0 as temp

       from saleorderdt where billno = in_billno;

       --定义一个游标变量

       ccrec cur_orderdt%rowtype;

       begin

             --for循环

             for ccrec in cur_orderdt loop

               

               declare--类型定义

               cursor cur_bal is select a.locatid,a.goodsid,a.ownerid,a.angleid,a.entid

               ,a.placenum - a.occupnum - nvl(c.basenum,0) as placenum

               from anglebalance a

               join batchcode b on a.goodsid = b.goodsid

                    and a.angleid = b.angleid and a.entid = b.entid

               left join (select sum(basenum) as basenum,ownerid,goodsid,locatid,entid,angleid

                    from goodsoccu

                    group by ownerid,goodsid,locatid,entid,angleid

                    ) c on a.locatid = c.locatid and a.goodsid = c.goodsid

                and a.ownerid = c.ownerid and a.angleid = c.angleid

                and a.entid = c.entid

                where a.goodsid = ccrec.goodsid

                order by b.valdate;

               temp int default 0;

               ccrbl cur_bal%rowtype;--定义游标变量

               begin

                 open cur_bal;--打开游标

                 loop --loop循环

                   fetch cur_bal into ccrbl;--提取数据到ccrbl

                   exit when cur_bal%notfound;--没有数据时退出

                   exit when temp >= ccrec.basenum;--数据分摊完成后退出

                   --批号分摊逻辑

    /*

    if 1=1 then

    else if 2>1 then

    else

    end if;

    */

                   if ccrbl.placenum >= ccrec.basenum - temp then

                      insert into kk_bal(locatid,goodsid,ownerid,angleid,entid,num,billno,billsn)

                      values(ccrbl.locatid,ccrbl.goodsid,ccrbl.ownerid,ccrbl.angleid

                      ,ccrbl.entid,ccrec.basenum - temp,ccrec.billno,ccrec.billsn);

                      commit;

                      temp := temp + ccrec.basenum;

                   else

                      insert into kk_bal(locatid,goodsid,ownerid,angleid,entid,num,billno,billsn)

                      values(ccrbl.locatid,ccrbl.goodsid,ccrbl.ownerid,ccrbl.angleid

                      ,ccrbl.entid,ccrbl.placenum,ccrec.billno,ccrec.billsn);

                      commit;

                      temp := temp + ccrbl.placenum;

                    end if;

                   --dbms_output.put_line('测试');

    --RAISE_APPLICATION_ERROR(-20991, '部门代码为空');--错误信息提示,类似sql serverraiseerror

                 end loop; --loop循环结束

                 close cur_bal;--关闭游标

               end;

             end loop;--for 循环结束

       end;

    end;

    ---------------------------------------相关文档说明

    游标-----内存中的一块区域,存放的是select 的结果

        

        游标用来处理从数据库中检索的多行记录(使用SELECT语句)。利用游标,程序可以逐个地处理和遍历一次检索返回的整个记录集。

         为了处理SQL语句,Oracle将在内存中分配一个区域,这就是上下文区。这个区包含了已经处理完的行数、指向被分析语句的指针,整个区是查询语句返回的数据行集。游标就是指向上下文区句柄或指针。

    两种游标:

    一、显示游标(需要明确定义!)

        显示游标被用于处理返回多行数据的SELECT 语句,游标名通过CURSOR.IS 语句显示地赋给SELECT 语句。

           PL/SQL中处理显示游标所必需的四个步骤:

           1)声明游标;CURSOR cursor_name IS select_statement

           2)为查询打开游标;OPEN cursor_name

           3)取得结果放入PL/SQL变量中;

                  FETCH cursor_name INTO list_of_variables;

                  FETCH cursor_name INTO PL/SQL_record;

           4)关闭游标。CLOSE cursor_name

           注意:在声明游标时,select_statement不能包含INTO子句。当使用显示游标时,INTO子句是FETCH语句的一部分。

       1、 显式游标

          select语句上 使用显式游标

          能明确访问结果集

             for循环游标

             参数游标

               解决多行记录的查询问题

             fetch游标

    二、隐式游标

           所有的隐式游标都被假设为只返回一条记录。

           使用隐式游标时,用户无需进行声明、打开及关闭。PL/SQL隐含地打开、处理,然后关掉游标。

           例如:

           …….

           SELECT studentNo,studentName

           INTO curStudentNo,curStudentName

           FROM StudentRecord

           WHERE name=gg;

           上述游标自动打开,并把相关值赋给对应变量,然后关闭。执行完后,PL/SQL变量curStudentNo,curStudentName中已经有了值。

       2、 隐式游标

         单条sql语句所产生的结果集合

           用关键字SQL表示隐式游标

            4个属性 %rowcount  影响的记录的行数  整数

                    %found     影响到了记录 true

                    %notfound  没有影响到记录 true

                    %isopen    是否打开  布尔值 永远是false

             多条sql语句 隐式游标SQL永远指的是最后一条sql语句的结果

             主要使用在update delete语句上      

    实际操作和例子:

       (1)FOR循环游标 (常用的一种游标)

     --<1>定义游标

     --<2>定义游标变量

     --<3>使用for循环来使用这个游标

      --前向游标 只能往一个方向走

      --效率很高

          declare

            --类型定义

            cursor cc is select empno,ename,job,sal

             from emp where job = 'MANAGER';

            --定义一个游标变量

            ccrec cc%rowtype;

          begin

             --for循环

             for ccrec in cc loop

                dbms_output.put_line(ccrec.empno||'-'||ccrec.ename||'-'||ccrec.job||'-'||ccrec.sal);

             end loop;       

          end;

       (2) fetch游标

         --使用的时候 必须要明确的打开和关闭

          declare

            --类型定义

            cursor cc is select empno,ename,job,sal

             from emp where job = 'MANAGER';

            --定义一个游标变量

            ccrec cc%rowtype;

          begin

            --打开游标

             open cc;

            --loop循环

             loop

                --提取一行数据到ccrec

                fetch cc into ccrec;         

                --判断是否提取到值,没取到值就退出

                --取到值cc%notfound false

                --取不到值cc%notfound true

                exit when cc%notfound;

                dbms_output.put_line(ccrec.empno||'-'||ccrec.ename||'-'||ccrec.job||'-'||ccrec.sal);            

             end loop;

            --关闭游标

             close cc;  

          end;

      游标的属性4

           %notfound  fetch是否提到数据 没有true 提到false

           %found      fetch是否提到数据 有true 没提到false

           %rowcount  已经取出的记录的条数

           %isopen    布尔值 游标是否打开

       (3)参数游标

     按部门编号的顺序输出部门经理的名字

         declare

           --部门

           cursor c1 is select deptno from dept;

           --参数游标c2,定义参数的时候

           --只能指定类型,不能指定长度  

           --参数只能出现在select语句=号的右侧

           cursor c2(no number,pjob varchar2) is select emp.* from emp

             where deptno = no and job=pjob;

           c1rec c1%rowtype;

           c2rec c2%rowtype;

           --定义变量的时候要指定长度

           v_job varchar2(20);

         begin

           --部门

            for c1rec in c1 loop

              --参数在游标中使用

              for c2rec in c2(c1rec.deptno,'MANAGER') loop

                dbms_output.put_line(c1rec.deptno||'-'||c2rec.ename);

              end loop;

            end loop;

         end;

      (4)引用游标/动态游标

           -- select语句是动态的

         declare

           --定义一个类型(ref cursor)弱类型    

           type cur is ref cursor;

             --强类型(返回的结果集有要求)

           type cur1 is ref cursor return emp%rowtype;

           --定义一个ref cursor类型的变量   

           cura cur;

           c1rec emp%rowtype;

           c2rec dept%rowtype;

         begin

      DBMS_output.put_line('输出员工')   ;       

           open cura for select * from emp;

           loop

             fetch cura into c1rec;   

             exit when cura%notfound;

             DBMS_output.put_line(c1rec.ename)   ;

           end loop ;

      DBMS_output.put_line('输出部门')   ;

           open cura for select * from dept;

           loop

             fetch cura into c2rec;   

             exit when cura%notfound;

             DBMS_output.put_line(c2rec.dname)   ;

           end loop;  

           close cura;

        end;

    好的代码像粥一样,都是用时间熬出来的
  • 相关阅读:
    metal的gpu query
    体积雾 global fog unity 及改进
    hdr rt format对颜色的影响
    unity deferred lighting
    unity linear space时 photoshop blend的正确设置
    unity linear work flow
    一些数据 bandwidth之类
    deferred rendering with msaa
    unity 显示mipmaplevel
    【转】在C#中使用SendMessage
  • 原文地址:https://www.cnblogs.com/jijm123/p/15376854.html
Copyright © 2011-2022 走看看