han8809 发表于 2017-12-14 18:39:14

PL/SQL入门随笔

  PL/SQL(Procedure Language/SQL)
  PLSQL是Oracle对sql语言的过程化扩展:
  在SQL命令语言中增加了过程处理语句(如分支、循环等),使SQL语言具有过程处理能力。
  SQL语言的数据操作能力与过程语言的数据处理能力相结合,使PLSQL面向过程,但比过程语言简单、高效、灵活、实用。
  不同数据库的SQL扩展
  Oracle:PL/SQL
  DB2:SQL/PL
  SQL Server:Transac-SQL(T-SQL)
  ===============================================================
  1、PL/SQL操作数据库效率最高
  2、继续学习存储过程,存储函数,触发器
  第一个程序
  --打开输出开关
  set serveroutput on
  declare
  -- 说明部分(变量,光标或者例外)
  begin
  --程序体
  dbms_output.put_line('hello world');
  end;
  /
  ===========================目录===============================
  1,PL/SQL的程序结构
  2,PL/SQL引用型变量和记录型变量
  3,PL/SQL中if语句的使用
  4,PL/SQL中循环语句的使用
  5,PL/SQL中光标
  6,PL/SQL例外
  7,程序设计方法
  ================PL/SQL的程序结构===============================
  declare
  说明部分(变量说明、光标说明、例外说明)
  begin
  语句序列(DML语句)
  exception
  例外处理语句
  end;
  /
  定义基本变量
  类型:char,varchar2,date,number,boolean,long
  举例:var1   char(15);
  married   boolean := true;
  psal      number(7,2);
  ================PL/SQL引用型变量和记录型变量====================
  emp_rec emp%rowtype emp_rec是emp的行,数组类型,可以获取EMP的所有字段,加.字段即可。(记录型变量)
  pename emp.ename%type 某个字段的类型,只能获取表中的一个字段。(引用型变量)
  ================PL/SQL中if语句的使用============================
  1、if 条件 then 语句1;
  语句2;
  end if;
  2、if 条件 then 语句1;
  else 语句2;
  end if;
  3、if 条件 then 语句1;
  elsif 语句 then 语句;
  else 语句;
  end if;
  -- 判断用户从键盘输入的数字
  set serveroutput on
  accept num prompt '请输入一个数字';
  declare
  pnum number:=#
  begin
  if pnum = 0 then dbms_output.put_line('你输入的是0');
  elsif pnum = 1 then dbms_output.put_line('你输入的是1');
  else dbms_output.put_line('你输入的是其他数字');
  end;
  /
  ================PL/SQL中循环语句的使用============================
  1.while循环:当循环条件成立时执行循环体,不成立时退出该循环
  WHILE total <= 25000 LOOP
  ...
  total := total + salary;
  END LOOP;
  2.loop循环:当循环条件不成立时执行循环体,成立时退出该循环
  Loop
  EXIT ;
  ...
  End loop;
  3.for循环:循环是连续的区间时
  FOR I IN 1..3 LOOP
  语句序列;
  END LOOP;
  ================PL/SQL中光标============================
  定义:就是一个结果集(result set)
  语法:
  CURSOR 光标名[(参数名 数据类型[,参数名 数据类型]...)]
  IS SELECT 语句;
  例如 cursor c1 is select ename from emp;
  实用:
  1.打开光标:
  open c1;打开光标执行查询
  2.关闭光标:
  close c1;关闭游标释放资源
  3.取一行光标的值:
  fetch c1 into pename;取一行到变量中
  fetch的作用:1)把当前指针指向的记录返回
  2)讲指针指向下一条记录
  属性:
  %found %notfound
  %isopen判断光标是否打开
  %rowcount影响的行数
  光标数的限制:默认打开最多300个光标

  修改光标数限制>  scopt属性:memory(只该当前实例),spfile(只改参数文件,数据库需要重启),both(两者都改)
  实例:
  set serveroutput on
  declare
  cursor cemp is select ename,salary from emp;
  pname emp.ename%type;
  psal emp.sal%type;
  begin
  -- 打开光标
  open cemp;
  loop
  -- 取一条记录
  fetch cemp into pename,psal;
  exit when cemp%notfound
  dbms_output.put_line(pname||'的薪水是'||psal);
  end loop
  -- 关闭光标
  close cemp
  end
  /
  实例1:给员工涨工资
  set serveroutput on
  declare
  --定义光标给哪些员工涨工资
  cursor cemp is select empno,empjob from emp;
  penmno emp.empno%type;
  pjob emp.empjob%type;
  begin
  --打开光标
  --把之前涨的工资回退回去
  rollback;
  open cemp;
  loop
  fetch cemp into penmno,pjob;
  exit when cemp%notfound
  -- 判断新员工的职位
  if pjob = 'president' then update emp set sal = sal+1000 where empno = pempno;
  elsif pjob = 'manager' then update emp set sal=sal +800 where empno = pempno;
  else update emp set sal = sal +400 where empno = pempno;
  end if;
  end loop
  close cemp;
  commit;
  dbms_output.put_line('涨工资完成');
  -- 对于oracle,默认的事务隔离级别是read committed
  -- 事务的acid:原子性,一致性,隔离性,持久性,
  end;
  /
  eg:
  --使用带参数的光标
  declare
  --定义一个带参数的游标
  cursor c_emp(dno number) is select ename from emp where deptno=dno;
  p_ename emp.ename%type;
  begin
  --打开游标时需要参入实参
  open c_emp(10);
  loop
  fetch c_emp into p_ename;
  exit when c_emp%notfound;
  DBMS_OUTPUT.PUT_LINE(p_ename);
  end loop;
  close c_emp;
  end;
  /
  =================PL/SQL例外============================
  例外是程序设计语言提供的一种功能,用来增强程序的健壮性和容错性
  1.No_date_found(没有找到数据)
  2.Too_many_rows (select...into语句匹配多个行)
  3.Zero_Divide (被零除)
  4.Value_error (算术或转换错误)如:负数在实数范围开平方,abc字符串 转换成 数字123
  5.Timeout_on_resource (等待资源时发生超时)比较典型的场景:分布式数据库
  --系统例外:no_data_found
  declare
  pename emp.ename%type;
  begin
  select ename into pename from emp where empno=222222;
  SYS.DBMS_OUTPUT.PUT_LINE(pename);
  exception
  when no_data_found then sys.dbms_output.put_line('没有对应的记录');
  when others then sys.dbms_output.put_line('其它例外');
  end;
  /
  --系统例外:too_many_rows;
  declare
  pename emp.ename%type;
  begin
  select ename into pename from emp where deptno=10;
  SYS.DBMS_OUTPUT.PUT_LINE(pename);
  exception
  when no_data_found then sys.dbms_output.put_line('没有对应的记录');
  when too_many_rows then sys.dbms_output.put_line('无法将多行记录赋值给一个普通变量');
  when others then sys.dbms_output.put_line('其它例外');
  end;
  /
  --系统例外:zero_divide 被0除
  declare
  pnum number;
  begin
  pnum:=1/0;
  exception
  when zero_divide then
  sys.dbms_output.put_line('0不能做除数');
  sys.dbms_output.put_line('0真的不能做除数');
  when others then sys.dbms_output.put_line('其它例外');
  end;
  /
  --系统例外:value_error算术或转换例外
  declare
  pnum number;
  begin
  pnum:='abd';
  exception
  when value_error then
  sys.dbms_output.put_line('算术或者转换错误');
  when others then sys.dbms_output.put_line('其它例外');
  end;
  /
  --自定义例外:查询50号部门的员工姓名
  set serveroutput on
  declare
  --定义光标
  cursor cemp is select ename from emp where deptno=50;
  pename emp.ename%type;
  --自定义例外
  no_emp_dataexception;
  begin
  open cemp;
  loop
  fetchcemp into pename;
  if cemp%notfound then raise no_emp_data;-- 抛出例外
  exit when cemp%notfound;
  end if;
  end loop;
  close cemp;-- 关闭光标,oracle自动启动pmon(process monitor)
  exception
  when no_emp_data then dbms_output.put_line('没有找到员工');
  when others then dbms_output.put_line('其他');
  end;
  /
  =====================程序设计方法============================
  需求分析->概要设计->详细设计->编码->测试->上线
  sql语句
  变量:1、初始值是多少2、最终值如何得到
页: [1]
查看完整版本: PL/SQL入门随笔