ORACLE PLSQL代码块学习

来源:互联网 发布:windows仿mac软件 编辑:程序博客网 时间:2024/06/16 12:47

背景:

本人小小实习生,oracle小白,,刚刚接触oracle的plsql块。记录下来这个学习过程,有错麻烦各位指出。

情景:

通过遍历查询一个表的结果集,得到结果集中每行结果中的其中一个字段的值,作为另一个查询的where语句查询条件。

之前的解决方案是在service层中遍历第一次查询的结果集,然后在这个遍历过程中多次调用第二个查询的方法,这就导致了在控制层和业务逻辑层只需要一个方法,但到了数据交换层需要分开为两个方法,很繁琐。恰巧之前有了解到oracle中可以通过存储函数实现这个功能,所以学习了下plsql块。


预备知识:

1.plsql代码块基本语法:

DECLARE

--这里声明一些变量②和游标 ③     

BEGIN     

--需要执行的逻辑 包括一些游标遍历

EXCEPTION

--发生异常的逻辑

END;

2.Oracle中变量类型

  这里我就列举下我目前使用到

    NUMBER(p,s)  数值类型   p表示精度 s表示小数长度  

例如 NUMBER(3,2) 表示的是 整数部分最大是1位,小数部分是2位的数

NUMBER等同于NUMBER(5)

    INT 

    VARCHAR

    CHAR 

    表%ROWTYPE   例如 emp表中有 id,name,dept 三个字段, emp_row  emp%ROWTYPE ,变量emp_row 同样有 id,name,dept三个字段。

    表.字段%TYPE   例如 emp.id 是number类型的,  emp_id  emp.id%type 则表示变量emp_id和emp表的id字段是相同的。

      3.Oracle游标

参考  http://www.iteye.com/topic/649874    


 游标的概念:游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。

  游标的作用:用于临时存储从数据库中提取的数据块。

          我将游标理解为java中jdbc中的resultset 对象,相当于一个记录查询结果的虚拟表,如果想拿到其中的数据需要遍历。

  游标的应用:

属性:

SQL%FOUND         FETCH有结果则为true

SQL%NOTFOUND             FETCH无结果为true

SQL%ISOPEN                    游标打开为true

SQL%ROWCOUNT           返回当前记录在游标中的行数


隐式游标 

 默认起名字SQL,不用我们开启也不用关闭.DML语句会自动生成隐式游标,主要起到程序控制的作用。

显示游标 

声明方式: CURSOR mycursor IS select * from emp where id >5; 查询结果将会记录到游标 mycursor中


REF游标(动态游标)

//TODO

 

游标的遍历方式

FOR   i  IN  mycursor LOOP              --这种方式会自动打开游标和关闭游标,因此务必不要重复打开,我出现过错误。DBMS_OUTPUT.PUTLINE(i.id||i.name||i.dept); --i就有点类似于foreach 中的那个变量
END LOOP; 

OPEN mycursor;LOOPFETCH mycursor INTO rs;                 --FETCH类似java中iterator遍历集合的next() 即拿到了下一个元素同时将迭代指针指向下下个元素EXIT WHEN mycursor%NOTFOUND;          END LOOP;


解决的问题:

根据产品id去查询改产品有几种颜色类型,遍历这些颜色类型,每一个颜色类型找到一张图片及一些其它相关的数据。总共需要查询三个表


  code:

declare   v_pid product.id%type default 877594;                  --为了以后学习存储函数做准备,这里设置默认值  cursor colorlist is   select color_type from productpic where productid=v_pid group by color_type;  v_colorid productpic.color_type%type;  cl_id int;  cursor v_result is  select * from(                     select p.cmsimage imageurl,                            p.productid pid,                            p.type imagetypeid,                            p.color_type colorid,                            c.color_name colorname,                            c.code colorcode,                            pt.name imagetypename,                            p.priority pr,                            pt.priority priority,                            p.id imageid                     from productpic p,catalog_imagecolor c,productpic_type pt                     where p.productid = v_pid                       and p.color_type = cl_id                       and p.type in(0,11)                       and p.color_type = c.id                       and p.type = pt.id                     order by p.priority              )where rownum=1;   begin                        for cl in colorlist loop           --遍历第一个游标 在游标遍历过程中遍历第二个游标            if cl.color_type<>0 then--            dbms_output.put_line('current colorid: '||cl.color_type);              cl_id :=cl.color_type;                         if v_result%isopen then                      close  v_result;              end if;              for rs in v_result              --遍历第二个游标                loop                  dbms_output.put_line('current imageurl: '||rs.imageurl);              end loop ;            end if;            end loop;            exception            when others then            dbms_output.put_line('error!');  end;

总结: 

        通过plsql可以看出,原先需要在业务逻辑层做的判断和数据交换层分成两个方法的麻烦事,实际上在oracle中只需要写到一个存储函数中就可以解决,同时也方便之后的维护和调用。

第一次写博客,希望自己能坚持下去。

  


0 0
原创粉丝点击