PL/SQL编程
declare --声明 v_sal teacher.sal%type; --创建变量 v_tname teacher.tname%type; v_rank varchar2(10); v_sal_rank VARCHAR2(20); begin select t.sal,t.tname into v_sal,v_tname --赋值 from teacher t where t.tno=1004; if v_sal < 2000 then --IF start v_rank:='临时工'; elsif v_sal >=2000 and v_sal <15000 then v_rank:='蓝领'; elsif v_sal >=15000 and v_sal <40000 then v_rank:='白领'; else v_rank:='金领'; end if; --IF end CASE v_rank --CASE START WHEN '临时工' THEN v_sal_rank:='小于2000'; WHEN '蓝领' THEN v_sal_rank:='[2000,15000)'; WHEN '白领' THEN v_sal_rank:='[15000,40000)'; ELSE v_sal_rank:='大于40000'; END CASE; --CASE END dbms_output.put_line(v_tname||':'||v_rank||',薪水:'||v_sal_rank); --输出 end;
1 -- 游标:是系统给我们用户开设的一个数据缓冲区!存放的是sql语句执行结果! 2 --每个游标区都有一个名字,用户通过游标一行一行的获取记录! 3 4 --01、隐式游标 在我们pl/sql中,程序执行sql语句时,自动创建!就是我们平常的sql语句 5 --02、显式游标 可以返回多行的查询! 6 --03、REF游标 用于处理运行时才能确定的动态sql 查询结果 7 8 --隐式游标属性 9 --01、sql%found 影响了一行或者多行,都返回true 10 --02、sql%notfound 没有影响行数,返回true 11 --03、sql%rowcount sql语句影响的行数 12 --04、sql%isopen 游标是否打开,始终为false 13 declare 14 tname teacher.tname%TYPE;--声明一个变量 15 CURSOR teacher_cursor IS SELECT tname FROM teacher; --声明游标 16 17 begin 18 OPEN teacher_cursor; --打开游标 19 FETCH teacher_cursor INTO tname; 20 21 --循环输出tname 22 WHILE teacher_cursor%FOUND 23 LOOP 24 dbms_output.put_line('第'||teacher_cursor%ROWCOUNT||'行,'||'教师的姓名:'||tname); 25 FETCH teacher_cursor INTO tname; 26 END LOOP; 27 CLOSE teacher_cursor; --关闭游标 28 29 end;
1 -- 触发器 2 -- :old 代表之前的值 3 --:new 代表之后现在的值 4 --这两个值 只能在for each row中使用 5 6 --update语句 :old :new 7 --insert语句 :new 8 --delete语句 :old 9 10 --创建一个teacher_log(只要有人动teacher表,数据就会记录在teacher_log表中) 11 12 CREATE TABLE teacher_log( 13 logid NUMBER NOT NULL, 14 old_value VARCHAR2(200), 15 create_date DATE, 16 log_type NUMBER, 17 tno NUMBER 18 ); 19 --给logid设置主键 20 ALTER TABLE teacher_log add CONSTRAINT pk_teacher_logid primary key(logid); 21 22 --创建序列 23 CREATE sequence sq_teacher_logid 24 minvalue 1 25 maxvalue 99999999 26 START WITH 1 27 increment BY 1 28 cache 20; 29 30 --创建触发器 or replace表示如果存在则修改 31 CREATE OR REPLACE TRIGGER tr_teacher 32 AFTER INSERT OR UPDATE OR DELETE --会在增修删之后出发 33 ON teacher FOR EACH ROW 34 35 --声明pl/sql开始 36 DECLARE 37 v_old_value teacher_log.old_value%TYPE; 38 v_type teacher_log.log_type%TYPE; 39 v_tno teacher_log.tno%TYPE; 40 BEGIN 41 IF inserting THEN 42 v_type:=1;--新增 43 v_tno:=:new.tno; 44 v_old_value:=:new.tno||'===='||:new.tname; 45 ELSIF deleting THEN 46 v_type:=2;--删除 47 v_tno:=:old.tno; 48 v_old_value:=:old.tno||'===='||:old.tname; 49 ELSE 50 v_type:=3;--修改 51 v_tno:=:old.tno; 52 v_old_value:=:old.tno||'===='||:old.tname||'===='||:new.sal; 53 END IF; 54 55 --将记录写入到teacher_log 56 INSERT INTO teacher_log 57 VALUES(sq_teacher_logid.nextval,v_old_value,SYSDATE,v_type,v_tno); 58 59 END tr_teacher;
1 --函数 function 2 CREATE OR REPLACE FUNCTION fn_teacher_tid( 3 f_tid VARCHAR2 4 ) 5 RETURN VARCHAR2 6 IS 7 f_result teacher.tid%TYPE; 8 9 BEGIN 10 IF LENGTH(f_tid)!=18 THEN 11 dbms_output.put_line('身份证不正确'); 12 ELSE 13 dbms_output.put_line('身份证正确'); 14 END IF; 15 --给返回值赋值 16 f_result:=SUBSTR(f_tid,1,6)||'*****'||SUBSTR(f_tid,15); 17 RETURN f_result; 18 19 END fn_teacher_tid; 20 21 22 --调用函数 23 SELECT fn_teacher_tid(110101198603304014) FROM dual;
1 --存储过程 一组完成特定功能的sql语句集 2 --新增教师 身份证不满足要求,抛出异常 3 4 CREATE OR REPLACE PROCEDURE pro_add_teacher 5 ( 6 p_tno teacher.tno%TYPE, 7 p_tname teacher.tname%TYPE, 8 p_tid teacher.tid%TYPE, 9 p_sal teacher.sal%TYPE 10 ) 11 IS 12 e_tid_validate EXCEPTION; 13 14 BEGIN 15 IF LENGTH(p_tid)!=18 --判断身份证号不满足18位 16 THEN --抛出异常 17 RAISE e_tid_validate; 18 END IF; 19 20 INSERT INTO teacher(tno,tname,tid,sal) 21 VALUES(p_tno,p_tname,p_tid,p_sal); 22 --提交事务 23 COMMIT; 24 25 --对异常进行处理 26 EXCEPTION WHEN e_tid_validate THEN 27 dbms_output.put_line('请输入正确的身份证号'); 28 WHEN OTHERS THEN 29 dbms_output.put_line('其他异常'); 30 END pro_add_teacher; 31 32 33 34 --调用存储过程 35 CALL pro_add_teacher(2001,'小黑黑','123456789123456789',5000);
1 2 DECLARE 3 v_temp NUMBER:=0;--循环变量 4 v_max_deptnum dept_loop.deptno%TYPE;--最大增加值 5 BEGIN 6 SELECT MAX(deptno) INTO v_max_deptnum FROM dept_loop; 7 LOOP --LOOP START 8 v_max_deptnum:=v_max_deptnum+1;--每次循环加1 9 INSERT INTO dept_loop 10 VALUES(v_max_deptnum,'部门'||v_max_deptnum,'地址'||v_max_deptnum); 11 v_temp:=v_temp+1;--每次循环变量加一 12 EXIT WHEN v_temp>99; 13 END LOOP; --LOOP END 14 15 v_temp:=0; --初始化循环变量 16 WHILE v_temp<100 LOOP --WHILE LOOP START 17 v_max_deptnum:=v_max_deptnum+1; 18 INSERT INTO dept_loop 19 VALUES(v_max_deptnum,'部门'||v_max_deptnum,'地址'||v_max_deptnum); 20 v_temp:=v_temp+1; 21 END LOOP; --WHILE LOOP END 22 23 FOR v_temp IN v_max_deptnum+1..v_max_deptnum+100 LOOP --FOR LOOP START 24 INSERT INTO dept_loop 25 VALUES(v_temp,'部门'||v_temp,'地址'||v_temp); 26 END LOOP; --FOR LOOP END 27 END;