Oracle之plsql及游标

Wesley13
• 阅读 636
--1、赋值
    --:= 赋值
        declare 
          var_name varchar2(10) :='&请输入名字';--&是一个提示输入的特殊符号,会打开一个输入框
          var_age number(3) :='&请输入年龄';
        begin
          dbms_output.put_line(var_name||'---'||var_age);--输入 ||是连接符号和java中的+一样
        end;

    --into 赋值
        declare 
          var_name varchar2(10);
          var_age number(3);
        begin
          select stuname,age into var_name,var_age from t_student where id = 2;
          dbms_output.put_line(var_name||'---'||var_age);
        end;

--2、 特殊类型:
    --%type 绑定某个表中的特定字段的类型
      declare
        v_name emp.ename%type;
        v_job emp.job%type;
      begin
        select ename,job into v_name,v_job from emp where emp.empno=3;
        dbms_output.put_line(v_name||'---'||v_job); 
      end;


   --%rowtype:行类型和表中的一行对应
      declare
        v_emp emp%rowtype; -- v_emp的类型是一个行类型 和emp的一条记录对应
      begin
        select * into v_emp from emp where empno=1;
        dbms_output.put_line(v_emp.ename||' '||v_emp.sal||' '||v_emp.job);
      end;
      
--3、if条件判断
      if语句
       语法格式:   if  条件 then
                   [ elsif 条件 then ]
                   [ elsif  条件 then]
                   [else ]
                    end if;
                    
                    
                    --实例
                    declare 
                        v_age number(3) :=&请输入年龄;
                    begin
                         if v_age = 18 then 
                                 dbms_output.put_line('18');
                         elsif v_age > 18 then 
                                 dbms_output.put_line('大于18');
                         else  dbms_output.put_line('小于18');
                         end if;
                    end;
               
--4、case
        case when  条件 then
             when  条件 then
               else
             end case;
             
             
             --实例
             declare 
                  v_age number(3) :=&请输入年龄;
             begin
                  case 
                        when  v_age = 18  then  dbms_output.put_line('18');--条件可以是一个定值也可以是>或者<
                        when  v_age = 19  then  dbms_output.put_line('19');
                        when  v_age = 20  then  dbms_output.put_line('20');
                        when  v_age = 21  then  dbms_output.put_line('21');
                        when  v_age = 22  then  dbms_output.put_line('22');
                        when  v_age > 23 then  dbms_output.put_line('大于23');     
                   else dbms_output.put_line('不知道');
                   end case;
             end;


--5、循环
       --5、1无限循环
              loop
                -- 循环体
                exit when 退出条件;
              end loop;
              
              --实例
                  declare 
                     v_num number(3) := 1;
                  begin
                    loop
                        dbms_output.put_line(v_num);
                        v_num := v_num+1;
                        exit when v_num > 10;
                    end loop;
                  end;
                    
         --5、2 while带条件的循环
             while 循环条件 loop
                   --循环体
               end loop;
               
              --实例
               declare
                 v_i number(5) := 1;
               begin
                 while v_i<10 loop
                   dbms_output.put_line(v_i);
                   v_i := v_i+1;
                   end loop;
               end; 
               
            --5/3 for循环:
                  --1.不用专门去声明循环变量
                  --2.每次只能自增一,
                  --3.要想实现循环降序需要在 in 后加 reverse

                  --实例
                     declare 
                     begin
                        for v_i in reverse 1..9 loop
                          dbms_output.put_line(v_i); 
                        end loop;
                     end;

                    
--6、goto关键字:跳转到指定的位置
          
       --实例:
            declare 
                  v_num number(5) := &请输入;
                 
            begin
                  if v_num = 18 then
                     dbms_output.put_line(18);
                     goto a1;
                   elsif v_num = 20 then 
                     dbms_output.put_line(20);
                     goto a2;
                   else  dbms_output.put_line('----------');
                         goto a3;
                   end if;
                   
                   <<a1>>
                        dbms_output.put_line('a1======');
                   <<a2>>
                        dbms_output.put_line('a2======');
                   <<a3>>
                        dbms_output.put_line('a3======');
            end;

--7、动态SQL语句:解决的是字符串格式的sql语句执行的问题
      EXECUTE IMMEDIATE dynamic_sql_string
      [INTO  define_variable_list]
      [USING bind_argument_list];
      
             declare
                 v_stuname t_student.stuname%type;
                 v_sql varchar2(100) := 'select stuname from t_student where id = :id';
                 v_id number(3) :=  &请输入查询的id; 
             begin 
                execute immediate v_sql into v_stuname using v_id;
                dbms_output.put_line(v_stuname);
             end;

--8、异常处理
             --8、1 系统异常
             no_data_found;没有找到数据的异常
             too_many_rows: 多行数据
             others 其他异常
             
             declare 
                    v_stuname t_student.stuname%type;
                    v_id t_student.id%type;
             begin 
                    -- 业务逻辑代码
                    v_id:=100;
                    select stuname into v_stuname from t_student where id = v_id;
                    dbms_output.put_line(v_stuname);
                    -- 异常处理代码 
                    
                    exception
                       when no_data_found then
                            dbms_output.put_line('找不到数据');
                       when too_many_rows then
                            dbms_output.put_line('数据过多');
                       when others then 
                            dbms_output.put_line('其他异常');
             end;
             
             --8、2 自定义异常
                   declare
                            v_i number(3) :=&请输入;
                            myexception exception; 
                   begin
                            if v_i = 2 then 
                               raise myexception;
                            end if;
                            dbms_output.put_line('==================');
                            
                            exception
                              when myexception then 
                                dbms_output.put_line('自定义异常触发了');
                              when others then 
                                dbms_output.put_line('不知道的异常');
                   end;
                     

游标:
    一.隐式游标:系统自动维护的,在我们做DML操作的时候系统会自动的维护这样一个游标
     名称叫:sql
           隐式游标提供的常用的属性:
            sql%found: boolean 找到数据 true
            sql%notfound: boolean 没有找到数据 true
            sql%rowcount: 数值型 影响的行数
            sql%isopen: 是否打开 dml中都是 false
              插入:select * from student;
           
           begin 
            update t_student set stuname='鲁睿骁' where id = 10;
            
            if sql%found then
              dbms_output.put_line('影响了'|| sql%rowcount ||'行记录');
            end if; 
            if sql%isopen then
               dbms_output.put_line('--------1--------');
            end if;
            if sql%notfound then
            dbms_output.put_line('-----------2-----------'); 
            end if;
            
           end;
           
    二.显示游标:处理多行数据,隐式游标配合显示游标使用
           2.1无参游标
           查询出学生表中的所有的记录:
         使用的步骤:
             1.声明游标
             2.打开游标
             3.循环提取数据
             4.关闭游标
             
             declare 
              v_student t_student%rowtype;
              --1.声明游标
              cursor mycursor is select * from t_student;
              v_count number(3):=0;
              begin 
              --2.打开游标
              open mycursor;
              --3.循环提取数据
              
              loop
                 --提取数据
                 -- 每循环一次从游标中取一条记录保存到v_student变量中
                 fetch mycursor into v_student;
                 --指定退出条件
                 exit when mycursor%notfound;
                 v_count := v_count+1;
                 dbms_output.put_line(v_student.id||v_student.stuname||v_student.sex);
              end loop;
              dbms_output.put_line('有'||v_count||'记录');
              --4.关闭游标
             close mycursor;
              end;  
              
              
             declare
             v_student t_student%rowtype;
             cursor mycursor is select * from student for update; -- 1. for update
          begin
            open mycursor;
               loop
             fetch mycursor into v_student;
             
             exit when mycursor%notfound;
             dbms_output.put_line(v_student.id||v_student.name||v_student.sex||v_student.birth);
             if v_student.birth is null then
               -- 2.在更新语句后加 current of 游标名称
                update t_student set stuname='鲁睿骁' where current of mycursor;
             end if;  
             end loop;
             commit;
            close mycursor;
          end; 
     
              
              
              
        2.2 有参游标
          根据姓名查询学生表中的所有的学生信息
          declare
           v_student t_student%rowtype;
           v_name t_student.stuname%type:='&请输入姓名';
           cursor mycursor(c_name varchar2) 
              is select * from t_student where stuname like '%'||c_name||'%';
          begin
            open mycursor(v_name);
            loop
               fetch mycursor into v_student;
               if mycursor%found then 
              dbms_output.put_line(v_student.id||'--'||v_student.stuname||'---'||v_student.age);
               else 
             exit;
               end if;
             end loop; 
             close mycursor;
          end;
          
          
          
           declare
            v_student t_student%rowtype;
            v_name t_student.stuname%type := '&请输入要查询的姓名';
            cursor mycursor -- 带有参数 
            is select * from t_student where stuname like '%'||v_name||'%'; 
          begin
            open mycursor; --打开的时候需要指定参数
             loop 
               fetch mycursor into v_student;
               if mycursor%found then
                  -- 有数据
                  dbms_output.put_line(v_student.id||v_student.stuname||v_student.sex);
               else 
                  -- 退出
                  exit;
               end if;
             end loop;
            close mycursor;
          end;

         2.3 游标循环时使用for循环提取

         declare
           v_name t_student.stuname%type := '&请输入';
           cursor mycursor is select * from t_student where stuname like '%'||v_name||'%';
         begin
           for v_student in mycursor loop
               update t_student set age=23;
              dbms_output.put_line(v_student.age||v_student.stuname||v_student.sex);
           end loop;
            commit;
         end;
         
         
    3.REF游标【动态游标】:是解决游标动态执行sql
          显示游标在声明的时候就必须制定sql语句
          动态游标:在打开的时候确定要执行的sql语句比显示游标更加的灵活
          缺点:不能使用for循环和更新行
          
         3.1 自定义ref游标
             通过REF游标查询出学生表中的所有的学生记录
            declare 
              type myreftype is ref cursor;-- 1.定义一个ref 类型
              myrefcursor myreftype;-- 2.声明一个myreftype类型的变量
              v_student t_student%rowtype;
              v_sql varchar2(100);
            begin
              v_sql:='select * from t_student';
              
               -- for 后及可以带'' 也可以直接是sql语句
            --open myrefcursor for select * from student; -- 打开游标的同时指定要执行的sql语句
              open myrefcursor for v_sql;
             loop
                fetch myrefcursor into v_student;
                exit when myrefcursor%notfound;
                 dbms_output.put_line(v_student.age||v_student.stuname||v_student.sex);
                
             end loop;
              close myrefcursor;
            end;
          
         
           3.2 sys_refcursor:系统提供的一个 ref cursor 类型
           
           declare 
              myrefcursor sys_refcursor; -- 声明一个变量类型是 refcursor 类型
              v_student t_student%rowtype;
              v_sql varchar2(100);
           begin 
              v_sql :='select * from t_student';
              open myrefcursor for v_sql;
              loop
             fetch myrefcursor into v_student;
                exit when myrefcursor%notfound;
                 dbms_output.put_line(v_student.age||v_student.stuname||v_student.sex);
                
              end loop;
               close myrefcursor;
           end;
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
5个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这