十八、Oracle学习笔记:PLSQL操作(含游标的操作)

一、PLSQL
1.什么是PLSQL
    plsql(procedural language sql)是过程化SQL语言,是Oracle数据库中特有的编程语法,可以进行一些复杂的计算和功能,其实是在基本的sql语言中加入了循环,判断等逻辑的一种数据库编程方式。运行在Oracle数据库上。
2.作用:
   可以更高效的进行大数据量的运算
3.优缺点:
   优点:效率高
   缺点:编写与维护性低,开发测试效率低,非面向对象语言。

二、格式与说明

--格式:
--基本格式:
  declare
     --变量的声明区域
  begin
     --业务逻辑区域
  exception
     --异常处理区域
  end;
  /
--最简格式:
  begin
    --业务逻辑区域
   end;
   /

 说明:变量的声明,变量名 类型名;变量名 类型名:=值 ;("="表示判断是否相等)。
           不赋值时,任何类型的数值为null,做运算时,null与任何值运算的结果都是null
           "/"必须要存在(脚本语言的分割线)
           plsql只是一个定义好的匿名代码块,只能在Oracle数据库中编译和运行一次。不会存储在Oracle中,如果想存储,需要定义成存储              过程,函数,触发器等。

--练习:使用最简格式 输出打印"hello plsql"
  set serveroutput on;--开启输出功能
  begin
    dbms_output.put_line('hello plsql');
  end;
  /
--练习:显示,姓名,年龄,出生年月日
  begin
    dbms_output.put_line('dodo'||'22'||'1996-12-18');
  end; 
  / 


  
三、plsql使用
1.注释
   (1):        --单行注释
   (2):       /*多行注释*/
2.格式
   declare   
   begin
   end;
    /

--练习:定义一个a,b,c;a为5,b为6,输出c的值
  declare
    a number(4):=5;
    b number(4):=6;
    c number(4);
  begin
    dbms_output.put_line('c='||c:=a+b);
  end; 
  /

--练习:定义变量name,age,并赋值输出
  declare
    name varchar2(8):='dodo';
    age number(4):=22;
  begin
    dbms_output.put_line('name='||name||',age='||age);
  end; 
  /

3.判断

--格式:
  if 条件 then 逻辑
  elsif 条件 then 逻辑
    ..
  else 逻辑
  end if;

--练习:定义一个变量gender 赋值,如果为'm',输出男,如果为'f',输出nv,否则输出人妖
  declare
    gender char(8):='m';
  begin
    if gender='m' then 
      dbms_output.put_line('男');
    elsif gender='f' then 
      dbms_output.put_line('女');
    else 
      dbms_output.put_line('人妖');
    end if;
  end;
  /
--练习:定义一个a,b;a为5,b为6,如果大于输出1,如果小于输出-1,如果相等,输出0
  declare
    a number(4):=5;
    b number(4):=6;
  begin
    if a>b then
      dbms_output.put_line(1);
    elsif a=b then
      dbms_output.put_line(0);
    else
      dbms_output.put_line(-1);
    end if;
   end; 
   /


4.循环

(1)loop循环

--格式
  loop
    --循环内容
  exit when 
    --结束条件
  end loop;   

--练习输出1~10
  declare 
    i number(4):=1;
  begin
    loop
      dbms_output.put_line(i);
      i:=i+1;
    exit when i>10;
    end loop;
  end;
  /
--练习从1加到100;
  declare
    i number(4):=1;
    a number(6):=0;
  begin
    loop
      a:=a+i;
      i:=i+1;
     exit when i>100;
     end loop;
       dbms_output.put_line(a);
  end;
  /

(2)while循环

--格式:
  while --条件 
  loop
    --逻辑
  end loop;
--练习:使用while循环计算100内基数之和
  declare 
    i number(4):=1;
    s number(4):=0;
  begin
    while i<100 loop
      s:=s+i;
      i:=i+2;           
    end loop;
    dbms_output.put_line(s);
  end;
  /

(3)for循环

--格式:
  for 变量 in 集合 loop
  end loop;
--集合必须是数字集合   例如 1..10
--使用for循环输出1到10
  declare
    i number(4):=1;
  begin
    for i  in 1..10 loop
      dbms_output.put_line(i);
    end loop;
  end;
  /
--for循环逻辑:循环中的循环赋值给变量


    
(4)plsql中使用DML和TCL

--没有特殊情况,直接使用
--练习:对表dept增加一条数据100,'qqq','cc',修改40号部门地址为'nanguan'
  begin
    insert into dept values(50,'qqq','cc');
    update dept set loc='nanguan' where deptno=40;
  end;
  /

 (5)plsql操作DDL语言

--格式:execute immediate 'DDL';
--练习:创建一张表 temp_1000 字段 id,number,name,varchar2(20)
  begin
    execute immediate 'create table temp_1000(id number(4),name varchar2(20))';
  end;
--在执行DDL时,可以进行DML(插入操作)
/*
   需要注意的是,不能直接insert into 
   因为DDL仅仅处在编译状态,此时数据库中还没有此表,所以直接insert会报错
   因为编译不通过,insert也应该写在execute immediate中
*/ 
--创建表temp_1001,id,name,同时插入数据 1 张三 2 李四 两条数据
  drop table temp_1001;
  begin
    execute immediate 'create table temp_1001(id number(4),name varchar2(20))';
    execute immediate 'insert into temp_1001 values(1,''zs'')';
    execute immediate 'insert into temp_1001 values(2,''ls'')';
    commit;
  end;
  /


(6)plsql中使用DQL:

--PLSQL中使用DQL语言,不是只为了查询,因为如果查询的话,普通的sql语句比较方便
--而plsql中使用DQL目的是将查询的数据数据封装到变量中进行其他的逻辑运算
--返回单行数据时
   select colName1,colName2 into 变量1,变量2 from ...
      
--练习:查询10号部门的名称和地址,封装到变量a和b中,进行拼接输出
  declare
    a varchar2(10);
    b varchar2(10);
  begin
    select dept.dname,dept.loc into a,b from dept where deptno=10;
    dbms_output.put_line(a||b);
  end;
  /

(7)使用%type 给变量匹配表中字段的类型

---变量名 表名.字段名%type,就可以自动匹配我们对应表数据的字段类型
--修改上一个练习
  declare
    a dept.dname%type;
    b dept.loc%type;
  begin
    select dept.dname,dept.loc into a,b from dept where deptno=10;
    dbms_output.put_line(a||b);
  end;
  /

(8)返回多行记录:
      1:使用游标,会将多条记录封装到游标中,那么就相当于ResultSet
      2:游标默认会在第一行的上面,每fetch一次,游标就会向下一行移动,当成功移动到下一行时,游标有一个状态,状态的值:found,当游标移动到最后一行时,再次fetch时,不会移动,但是状态变为notfound.
      3:使用循环进行遍历

--格式:
  declare
    cursor 游标名 is select语句;
  begin
    open 游标名;
    loop
      fetch 游标名 into 变量1,变量2....
    exit when 结束条件(游标名%notfound);
    end loop;
    close 游标名;
  end;
  /
--练习:输出显示10号部门员工姓名,职位,工资
--使用loop
  declare
    cursor c is select ename,job,sal from emp where deptno=10; 
    n emp.ename%type;
    job emp.job%type;
    sal emp.sal%type;
  begin
    open c;
    loop
      fetch c into n,job,sal;     
    exit when c%notfound; 
      dbms_output.put_line(n||'  '||job||'  '||sal); 
    end loop;
    close c;
  end;
  /                               
      
--使用while
  declare
    cursor c is select ename,job,sal from emp where deptno=10; 
    n emp.ename%type;
    job emp.job%type;
    sal emp.sal%type;
  begin
    open c;
    --先移动一次游标
    fetch c into n,job,sal;
    while c%found
    loop
      dbms_output.put_line(n||'  '||job||'  '||sal); 
      fetch c into n,job,sal;
    end loop;
    close c;
  end;
  /

===============================================================================================

--练习
--1.计算1*2*3*4*5*7*8*9*10的结果

  set serveroutput on;
  declare
    s number(8):=1;
    i number(4):=1;
  begin
    loop
      if i=6 then s:=s;
      elsif i!=6 then s:=s*i;
      end if;
      i:=i+1;
      exit when i>10;
    end loop;
    dbms_output.put_line(s);
  end;


--2.查询7398员工的工资,将其一半修改成奖金,保存到列表中

  declare 
    sal_info emp.sal%type;
  begin
    select sal into sal_info from emp where empno=7698;
       sal_info:=sal_info/2;
       update emp set comm:=sal_info where empno=7698;
       dbms_output.put_line(sal_info); 
  end;


--3.查询20部门的员工信息,显示编号,名称,职位(loop循环,while循环)

 declare
    cursor c is select empno,ename,job from emp where deptno=20;
    en emp.empno%type;
    em emp.ename%type;
    job emp.job%type;
  begin
    open c;
         loop
           fetch c into en,em,job;
           dbms_output.put_line(en||'   '||em||'   '||job);
           exit when c%notfound;
         end loop;
    close c;
    end;

  declare
    cursor c is select empno,ename,job from emp where deptno=20;
    en emp.empno%type;
    em emp.ename%type;
    job emp.job%type;
  begin
    open c;
          fetch c into en,em,job;
         while c%found loop
           dbms_output.put_line(en||'   '||em||'   '||job);
           fetch c into en,em,job;
         end loop;
    close c;
    end;
    

猜你喜欢

转载自blog.csdn.net/qq_38741971/article/details/81429336