经典SQL学习笔记 (七) - pl/sql编程一
2015-03-12 16:02
453 查看
pl/sql编程
------------------------pl/sql编程---------------------------- (procedual):oracle 在标准sql语言上的扩展 简单分类: 块(存储过程,函数,包,触发器) declare --定义部分 begin --执行部分 exception ---异常处理部分 end; --结束 set serveroutput on --输出开关开启 1.-----------------------第一个块------------------------------------------------ declare v_name varchar2(20); begin v_name:='王照陆爱编程'; -- (:= 赋值) dbms_output.put_line(v_name); end; 2.------------------------------------------------------------------------------- declare v_ename varchar2(20); begin select ename into v_ename from emp where empno=7788; dbms_output.put_line(v_ename); end; 3.------------------------------------------------------------------------------ 例子:根据员工的编号,查询出姓名、工资,并把姓名和工资输出 declare v_ename varchar2(20); v_sal number(7,2); begin select ename,sal into v_ename, v_sal from emp where empno=&no; --&no:从键盘输入 dbms_output.put_line(v_ename || '------'|| v_sal); end; 4.------------------------------------------------------------------------------ --插入一条数据,把插入的数据输出----------------------------------------------------- ----建表 create table wzl( deptno number, dname varchar2(20), loc varchar2(10) ); returning----用于语句中所影响到的数据行 into :把表中的信息赋予一个变量 --方法一: insert into values(80,'dd','dd'); declare v_deptno number; v_dname varchar2(20); v_loc varchar2(10); begin insert into wzl values(80,'dd','dd') returning deptno,dname,loc into v_deptno,v_dname,v_loc; dbms_output.put_line(v_deptno || '---'|| v_dname||'---'||v_loc); end; --方法二: declare v_info varchar2(30); begin insert into wzl values(80,'dd','dd') returning deptno||dname||loc into v_info; dbms_output.put_line(v_info); end; --更新一条数据,把更新的数据输出---------------------------------------------------- declare v_deptno number; v_dname varchar2(20); v_loc varchar2(10); begin update wzl set dname='王照陆' where dname='dd' returning deptno,dname,loc into v_deptno,v_dname,v_loc; update wzl set loc='南京' where loc='dd' returning deptno,dname,loc into v_deptno,v_dname,v_loc; dbms_output.put_line(v_deptno || '---'|| v_dname||'---'||v_loc); end; --删除一条数据,把删除的数据输出------------------------------------------------------ --复合类型、记录类型---------------------------------------------------------------- 语法: type 记录类型的名字 is record ( v1 type, v2 type, ..... ); -------------------------------------------------------------------------------- declare type rec is record( deptno number(4), dname varchar2(20), loc varchar2(10)); v_r rec; begin update wzl set deptno=80 where deptno=60 returning deptno,dname,loc into v_r.deptno,v_r.dname,v_r.loc; dbms_output.put_line(v_r.deptno || '---'|| v_r.dname||'---'||v_r.loc); end; --数组类型----------------------------------------------------------------------- 语法: type 数组类型名 is varray (size)of date_type declare type array is varray(4) of varchar2(10); v_a array; begin v_a:=array('dd','cc','ff','gg');--对数组的 赋值 dbms_output.put_line(v_a(1)||'--'||v_a(2)||'--'||v_a(3)||'--'||v_a(4)); dbms_output.put_line(v_a.first||'--'||v_a.last); end; first --取数组下标的最小值 last --取数组下标的最大值 --%type---------------------------------------------------------------- 语法: 表名.字段名%type --%rowtype----------------------------------------------------------------------- --记录类型 用法:表%rowtype --pl/sql的控制语句---------------------------------------------------------------- if 条件 then elsif 条件 then ......... else end if; ----------------- 1.输入雇员的编号,查询雇员的工资, 如果工资小于1500,显示工资太低了 如果工资大于5000,显示工资太高了 declare v_sal emp.sal%type; v_comment varchar2(20); begin select sal into v_sal from emp where empno=&no; if v_sal<1500 then v_comment:='工资太低了'; elsif v_sal>5000 then v_comment:='工资太高了'; end if; dbms_output.put_line(v_comment); end; 2.输入雇员的编号,查询出雇员的姓名和雇佣日期, 如果雇佣日期万元万余晚于1988-01-01,奖金是1600, 如果雇佣日期万元万余晚于1990-01-01,奖金是800, 其他情况,奖金是2400,请输出雇员的姓名,受雇日期和奖金 declare v_info emp%rowtype; v_bonus number(10); begin select * into v_info from emp where empno=&no; if v_info.hiredate>to_date('1988-01-01','yyyy/mm/dd') then v_bonus:=1600; elsif v_info.hiredate>to_date('1990-01-01','yyyy/mm/dd') then v_bonus:=800; else v_bonus:=2400; end if; dbms_output.put_line(v_info.ename||'--'||v_info.hiredate||'--'||v_bonus); end; -------------------------------------------------------------------------------- case 语句 case 条件表达式 when 结果1 then when 结果2 then ... else 结果 end case; 1.输入成绩,是A,输出excellent, 是B 输出verygood, 是C,输出good, 其他显示 no grade declare v_grade char(1):='&grade'; v_comment varchar2(10); begin case v_grade when 'A' then v_comment:='excellent'; when 'B' then v_comment:='verygood'; when 'C' then v_comment:='good'; else v_comment :='no grade'; end case; dbms_output.put_line(v_comment); end; --循环语句----------------------------------------------------------------------- loop 语法: loop ..... exit when 条件 end loop; declare v_int number:=1; begin dbms_output.put_line(v_int); loop v_int:=v_int+1; dbms_output.put_line(v_int); exit when v_int>=10; end loop; end; ------------------ while 循环 语法: while 条件 loop ......... end loop; declare v_int number:=1; begin while v_int<=10 loop dbms_output.put_line(v_int); v_int:=v_int+1; end loop; end; ------------------ for 循环 for 变量名 in [reverse] 最小值...最大值 loop ..... end loop 变量名:名字,不需要定义,number in:自动加1 in reverse :自动减1 begin for v_int in reverse in 1...10 loop dbms_output.put_line(v_int); end loop; end; -----------练习题部分------------------------------------------------------------- 1、创建一张表,先向表中插入数据10,然后依次插入20到25的值2遍 create table temp_wzl(no number(3)); declare v_num number(2):=10; begin insert into temp_wzl(no) values(v_num); for v_i in 1..2 loop for v_num in 20..25 loop insert into temp_wzl(no) values(v_num); end loop; end loop; end; 2、定义一个数组类型,并给这个数组类型赋值SALESMAN,CLERK,MANAGER,ANALYST并针对数组中的每个岗位,求出 该岗位的雇员人数,并输出岗位和人数 declare type jobs_array is varray(4) of varchar2(20); v_job jobs_array; v_counter number(2); begin v_job:=jobs_array('SALESMAN','CLERK','MANAGER','ANALYST'); for i in v_job.first..v_job.last loop select count(*) into v_counter from emp where job=v_job(i); dbms_output.put_line(v_job(i)||'---'||v_counter); end loop; end; 3、求出100到110之间的素数 declare v_num number(3):=100; v_i number(3); v_counter number(3):=0; begin while v_num<110 loop v_i:=2; loop if mod(v_num,v_i)=0 then v_i:=0; exit; end if; v_i:=v_i+1; exit when v_i>v_num-1; end loop; if v_i>0 then v_counter:=v_counter+1; dbms_output.put_line('第'||v_counter||'的素数'||v_num); end if; v_num:=v_num+1; end loop; end; --块存储过程(procedure)--------------------------------------------------------- or replace --替换 create [or replace] procedure 存储过程的名字(arg1 {in|out|inout} type1,arg2 {in|out|inout} type2.....) is|as <变量,常量的声明> begin ..... exception .... end; 模式 in:将实参的值传递给形参,进入存储过程的内部,但只能读不能写 out:会忽略调用的实参值,返回时,形参的值会赋予实参,(变量) inout: 例:输入雇员名,返回雇员的工资 create or replace procedure sp1(spno in number,spsal out number) is begin select sal into spsal from emp where empno=spno; end; exec 存储过程名(); call 存储过程名(); 块中进行调用 declare v1 number(7,2); begin sp1(7788,v1); dbms_output.put_line(v1); end; --------------------------- create or replace procedure sp2(spno in number) is spsal emp.sal%type; begin select sal into spsal from emp where empno=spno; dbms_output.put_line(spsal); end; -------------------------------------------------------------------------------- 例:写一个过程,输入员工的编号,返回该雇员的姓名和工作 create or replace procedure sp1_wzl(spno number,spname out varchar2,spjob out varchar2) --in可以省略不写 as begin select ename,job into spname,spjob from emp where empno=spno; end; declare v_name varchar2(10); v_job varchar2(10); begin sp1_wzl(7788,v_name,v_job); dbms_output.put_line(v_name||'---'||v_job); end; --函数--------------------------------------------------------------------------- create function 函数名(arg1 {in|out|inout} type1,arg2 {in|out|inout} type2.....) is|as <变量,常量的声明> begin ..... return expression; exception .... end; 输入雇员的编号,返回雇员的一年的总收入 create or replace function f1(spno number) return number is v_income emp.sal%type; begin select nvl2(comm,sal+comm,sal)*12 into v_income from emp where empno=spno; return v_income; end; declare v1 emp.sal%type; begin v1:=f1(7788); dbms_output.put_line(v1); end; -------------------------------------------------------------------------------- 例:写一个过程,输入员工的编号,返回该雇员的姓名 create or replace function f_name(spno number) return varchar2 as v_name emp.ename%type; begin select ename into v_name from emp where empno=spno; return v_name; end; declare v1 emp.ename%type; begin v1:=f_name(7788); dbms_output.put_line(v1); end; --游标(cursor)----------------------------------------------------------------- 分类:静态游标(显示游标、隐式游标)、动态游标 静态游标 显示游标(过程) 1、声明游标 cursor 游标名 is select 语句; 2、打开游标 open 游标名; 3、提取数据 fetch 游标名 into 变量(记录类型) 4、关闭游标 close 游标名; 游标的属性: noutfound: 没有发现 found:发现 isopen:是否打开 rowcount:行数,访问或修改了多少条数据 用法: 游标名%属性
相关文章推荐
- 经典SQL学习笔记 (八) - pl/sql编程二
- 【数据库学习笔记】Oracle_03_PL/SQL深入:游标编程,自定义异常
- PL/SQL函数学习笔记:decode函数
- PL/Sql 学习笔记---(一)
- Oracle笔记 十二、PL/SQL 面向对象oop编程
- PL/SQL学习笔记-游标
- PL/SQL学习笔记之记录
- PL\SQL 学习笔记(三) PL中的sql语句
- Oracle 学习笔记 19 -- 触发器和包浅析(PL/SQL)
- pl/sql学习笔记之二 plsql basics
- Oracle PL/SQL语句基础学习笔记(上)
- 经典SQL语句大全--------------学习笔记
- PL/SQL 学习笔记3
- 经典SQL学习笔记 (二)-单行函数
- Oracle PL/SQL 学习笔记(三)
- ORACLE PL/SQL 集合学习笔记(三)
- Oracle PL/SQL 学习笔记 (2)
- Oracle PL/SQL 学习笔记(二)
- PL/SQL学习笔记一
- pl/sql学习笔记之五 错误管理 error mgt