一、匿名块
1、使用returning ... INTO 保存增删改表数据时的一些列的值
(01)增加数据时保存数据
DECLARE
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
INSERT INTO emp(empno,ename,JOB,sal,comm,deptno) VALUES(&no,'zhaoliu','deve',3000,500,10) RETURNING ename,sal INTO v_ename,v_sal;
dbms_output.put_line(v_ename || ','||v_sal);
end; ---打开控制台输出开关
SET serveroutput ON; (02)修改数据时保存数据
DECLARE
v_ename emp.ename%TYPE;
v_sal emp.sal%type;
BEGIN
UPDATE emp SET sal=sal+100 WHERE empno=&no RETURNING ename,sal INTO v_ename,v_sal;
dbms_output.put_line(v_ename || ','||v_sal);
END; (03)删除数据时保存数据
DECLARE
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
DELETE FROM emp WHERE empno=&no RETURNING ename,sal INTO v_ename,v_sal;
dbms_output.put_line(v_ename || ','||v_sal);
END; 二、分支结构
1、if
IF 条件 THEN 结果;
END IF; IF 条件 THEN 结果;
ELSE 结果;
END IF; IF 条件 THEN 结果;
elsif 条件 THEN 结果;
....
ELSE 结果;
END IF; ---查询一个员工薪水,判断员工薪水如果大于3000,输出他是一个白领;如果工资小于等于3000大于1500,输出他是一个蓝领;其它情况输出是一个灰领;
DECLARE
v_sal emp.sal%TYPE;
BEGIN
SELECT sal INTO v_sal FROM emp WHERE empno=&no;
IF v_sal>3000 THEN
dbms_output.put_line('白领');
elsif v_sal>1500 THEN
dbms_output.put_line('蓝领');
ELSE dbms_output.put_line('灰领');
END IF;
END; 2、case:
格式一:
CASE WHEN 条件 THEN 结果;
WHEN 条件 THEN 结果;
...
ELSE 结果;
END CASE; 格式二:
CASE 条件表达式 WHEN 值1 THEN 结果1;
WHEN 值2 THEN 结果2;
....
ELSE 结果m;
END CASE; ---输入一个成绩,判断该成绩等级,如果在99~90之间,返回为A,如果在89~80之间,返回为B,如果在79~70之间,返回C,其它返回为D
DECLARE
v_score NUMBER(3);
v_flag VARCHAR2(1);
BEGIN
v_score:=&score;
CASE trunc(v_score/10) WHEN 9 THEN v_flag:='A';
WHEN 8 THEN v_flag:='B';
WHEN 7 THEN v_flag:='C';
ELSE v_flag:='D';
END CASE;
dbms_output.put_line(v_score || ',该 成绩的等级为:' || v_flag);
END; 三、循环结构
1、直到型循环
loop
执行循环体;
exit WHEN 条件;
END loop; ---在控制台输出1~5
DECLARE
v_i NUMBER(1):=1;
BEGIN
loop
dbms_output.put_line(v_i);
v_i:=v_i+1;
exit WHEN v_i>5;
END loop;
end; 2、while:
while 条件
loop
执行循环体;
END loop; ---在控制台输出1~5
DECLARE
v_i NUMBER(1):=1;
BEGIN
while v_i<=5
loop
dbms_output.put_line(v_i);
v_i:=v_i+1;
END loop;
end; 3、fOR:
FOR 循环变量 IN 最小值..最大值
loop
执行循环体;
END loop; ---在控制台输出1~5
BEGIN
for v_i in 1..5
loop
dbms_output.put_line(v_i);
END loop;
end; 练习:
创建一张表,只包含一个字段id
先在表中插入一条记录5
然后将10—20之间的数插入两遍 四、存储过程
语法:
CREATE [OR REPLACE] PROCEDURE 存储过程名(形参1 IN|out 数据类型,形参2 IN|out 数据类型...)
IS | AS
定义部分;
begin
执行部分;
exception
异常部分;
END; 调用过程:
exec 存储过程名(实参...);
call 存储过程名(实参...); ---如果调用的是无参存储过程,过程名后面必须() 1、创建一个无参存储过程
CREATE PROCEDURE pro_demo1
IS
BEGIN
INSERT INTO dept VALUES(50,'deve','nanjing');
end; exec pro_demo1;
call pro_demo1(); 2、创建一个输入参数存储过程
---根据输入的员工工号和新的月薪修改数据库中该 员工的薪水
CREATE OR REPLACE PROCEDURE pro_demo1(NO emp.empno%TYPE,newsal emp.sal%TYPE)
is
BEGIN
update emp set sal=newsal where empno=no;
end; 一个为雇员加薪的过程
CREATE OR REPLACE PROCEDURE pro_demo1(NO emp.empno%TYPE,addsal emp.sal%TYPE)
is
BEGIN
UPDATE emp SET sal=sal+addsal WHERE empno=NO;
end; CALL pro_demo1(7788,10000); SELECT * FROM emp; 3、创建一个即有输入参数也有输出参数存储过程
---输出指定员工的姓名和工资
CREATE OR REPLACE PROCEDURE pro_demo2(NO emp.empno%TYPE,NAME out emp.ename%TYPE,salary out emp.sal%TYPE)
IS
BEGIN
SELECT ename,sal INTO NAME,salary FROM emp WHERE empno=NO;
END; --使用匿名块调用存储过程
DECLARE
v_name VARCHAR2(30);
v_sal NUMBER(7);
BEGIN
pro_demo2(&no,v_name,v_sal);
dbms_output.put_line(v_name || ',' || v_sal);
end; 五、函数
CREATE OR REPLACE FUNCTION 函数名(形参 数据类型,...) RETURN 数据类型
IS
定义部分;
BEGIN
执行部分;
exception
异常部分;
END; ---返回指定员工的年薪
CREATE OR REPLACE FUNCTION fun_demo1(NO emp.empno%TYPE) RETURN NUMBER
IS
v_salary NUMBER(10,2);
BEGIN
SELECT sal*12 INTO v_salary FROM emp WHERE empno=NO;
RETURN v_salary;
END; SELECT fun_demo1(7788) FROM dual; ---写一个函数,返回用户的姓名,入职日期,工资
CREATE OR REPLACE FUNCTION fun_demo2(NO emp.empno%TYPE) RETURN VARCHAR2
IS
v_ename emp.ename%TYPE;
v_hiredate varchar2(50);
v_sal emp.sal%TYPE;
v_info varchar2(200);
BEGIN
SELECT ename,to_char(hiredate,'yyyy-mm-dd'),sal INTO v_ename,v_hiredate,v_sal FROM emp WHERE empno=NO;
v_info:=v_ename ||','|| v_hiredate ||','|| v_sal;
RETURN v_info;
end; SELECT fun_demo2(7788) FROM dual; 存储过程和函数的区别:
1.返回值的区别,函数返回值只有一个,而存储过程是通过输出参数来返回,可以有多个
2.调用的区别,函数可以在查询语句中直接调用,而存储过程必须单独调用
3.应用场合的区别,函数一般用来计算并返回计算的结果,而存储过程一般用来执行特定的操作,如创建表、创建用户等DDL语句 五、包,里面包含的内容:存储过程,函数
语法:包括两个部分
声明部分:
CREATE OR REPLACE PACKAGE 包名
IS
声明内容;
END; 包体的实体:
CREATE OR REPLACE PACKAGE BODY 包名
is
实现部分;
end; CREATE OR REPLACE PACKAGE pac_demo1
IS
PROCEDURE pro_demo1(NO emp.empno%TYPE,salary emp.sal%TYPE);
PROCEDURE pro_demo2(NO emp.empno%TYPE);
FUNCTION fun_demo1(NO emp.empno%TYPE) RETURN NUMBER;
end; create or replace package body pac_demo1
IS
PROCEDURE pro_demo1(NO emp.empno%TYPE,salary emp.sal%TYPE)
is
BEGIN
UPDATE emp SET sal=salary WHERE empno=NO;
END;
PROCEDURE pro_demo2(NO emp.empno%TYPE)
IS
BEGIN
DELETE FROM emp WHERE empno=NO;
END;
FUNCTION fun_demo1(NO emp.empno%TYPE) RETURN NUMBER
IS
v_salary number(10,2);
BEGIN
SELECT sal*12 INTO v_salary FROM emp WHERE empno=NO;
RETURN v_salary;
END;
end; CALL pac_demo1.pro_demo1(7788,20000);
SELECT * FROM emp;
CALL pac_demo1.pro_demo2(7788);
select pac_demo1.fun_demo1(7369) from dual; --1.创建一个包,包含一个为雇员加薪的过程,一个为雇员减薪的过程
CREATE OR REPLACE PACKAGE pac_test1
IS
PROCEDURE addsal(NO emp.empno%TYPE,addsal emp.sal%TYPE);
procedure minussal(no emp.empno%type,minussal emp.sal%type);
END; CREATE OR REPLACE PACKAGE body pac_test1
IS
PROCEDURE addsal(NO emp.empno%TYPE,addsal emp.sal%TYPE)
is
BEGIN
UPDATE emp SET sal=sal+addsal WHERE empno=NO;
end;
PROCEDURE minussal(NO emp.empno%TYPE,minussal emp.sal%TYPE)
IS
BEGIN
UPDATE emp SET sal=sal-minussal WHERE empno=NO;
end;
END; --2.编写一个过程,验证用户登陆。如果用户名、密码匹配,输出Y,否则输出N emp表中的ename为用户名 empno为密码
CREATE OR REPLACE PROCEDURE pro_test2(username VARCHAR2,PASSWORD NUMBER,flag out VARCHAR2)
IS
v_count number(2);
BEGIN
SELECT count(empno) INTO v_count FROM emp WHERE ename=username AND empno=PASSWORD;
IF v_count>0 THEN flag:='Y';
ELSE flag:='N';
END IF;
END; --3.编写一个函数,根据雇员编号,计算调整后的工资
如果该雇员从事经理工作,且工资大于3000,则工资上涨20%,否则上涨35%
其他情况均上涨10%,输出雇员编号、姓名、上涨后的工资 CREATE OR REPLACE FUNCTION fun_test3(NO emp.empno%TYPE) RETURN VARCHAR2
IS
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
v_newsal emp.sal%TYPE;
v_job emp.job%type;
v_info varchar2(100);
BEGIN
SELECT ename,sal,JOB INTO v_ename,v_sal,v_job FROM emp WHERE empno=NO;
IF upper(v_job)='MANAGER' THEN
IF v_sal>3000 THEN
v_newsal:=v_sal*1.2;
ELSE v_newsal:=v_sal*1.35;
END IF;
ELSE v_newsal:=v_sal*1.1;
END IF;
v_info:= NO || ',' || v_ename || ',' || v_newsal;
RETURN v_info;
end; --4.创建一个包
包中含有一个存储过程,实现涨工资的功能,输入雇员姓名,如果其工作年限超过20年,工资增加2000
工作年限在10-20年,工资增加1000,工作年限在5-10年,工资增加500,输出雇员姓名和增涨后的工资
包中还含有一个函数,实现输入工资,判断工资如果大于4500,返回1,否则返回0 CREATE OR REPLACE PACKAGE pac_test4
IS
PROCEDURE pro_addsal(NAME emp.ename%TYPE,info out VARCHAR2);
FUNCTION fun_sal(salary emp.sal%TYPE) RETURN NUMBER;
end; CREATE OR REPLACE PACKAGE body pac_test4
IS
PROCEDURE pro_addsal(NAME emp.ename%TYPE,info out VARCHAR2)
IS
v_year NUMBER(5);
v_sal emp.sal%TYPE;
BEGIN
SELECT trunc(months_between(SYSDATE,hiredate)/12),sal INTO v_year,v_sal FROM emp WHERE upper(ename)=upper(NAME);
IF v_year>20 THEN v_sal:=v_sal+2000;
elsif v_year>=10 THEN v_sal:=v_sal+1000;
elsif v_year>=5 THEN v_sal:=v_sal+500;
END IF;
info:=NAME || ','||v_sal;
end;
FUNCTION fun_sal(salary emp.sal%TYPE) RETURN NUMBER
IS
v_flag NUMBER(1);
BEGIN
IF salary>4500 THEN
v_flag:=1;
ELSE v_flag:=0;
END IF;
RETURN v_flag;
end;
END; 六、游标:
1、显示游标(查)、隐式游标(增删改)
使用显示游标有四个步骤:
(01):声明游标:cursor 游标名 IS 查询语句;
(02):打开游标:open 游标名;
(03):获取数据:fetch 游标名 INTO 变量名;
(04):关闭游标:close 游标名; 游标属性:
%found:是否发现数据,如果发现,返回true,否则返回false
%notfound:是否没有数据,如果没有,返回true,否则返回false
%isopen:是否打开,如果打开,,返回true,否则返回false
%rowcount:返回涉及的行数 DECLARE
CURSOR cur IS SELECT * FROM dept;
v_dept dept%rowtype;
BEGIN
OPEN cur;
fetch cur INTO v_dept;
loop
dbms_output.put_line(v_dept.deptno || ','|| v_dept.dname || ','||v_dept.loc);
fetch cur INTO v_dept;
exit WHEN cur%notfound;
END loop;
CLOSE cur;
end; ---使用for循环读取游标指向的数据,打开游标、获取游标数据、关闭游标都自动
DECLARE
CURSOR cur IS SELECT * FROM dept;
BEGIN
FOR v_dept IN cur
loop
dbms_output.put_line(v_dept.deptno || ','|| v_dept.dname || ','||v_dept.loc);
END loop;
end; 2、隐式游标:游标名为SQL,增删改 ---修改指定员工的工资,如果员工不存在,提示员工不存在,如果存在,输出更新数据的行数
BEGIN
UPDATE emp SET sal=sal*1.2 WHERE empno=&no;
IF SQL%found THEN
dbms_output.put_line('更新数据的行数为:' || SQL%rowcount);
ELSE
dbms_output.put_line('对不起,该用户不存在');
END IF;
end; 六、异常:
1、预定义异常:有异常号也有异常名
DECLARE
v_emp emp%rowtype;
BEGIN
SELECT * INTO v_emp FROM emp WHERE empno=&no;
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; 2、非预定义异常:有异常号没有异常名
3、自定义异常:没有异常号也没有异常名 七、触发器
1、DML触发器: CREATE OR REPLACE TRIGGER 触发器名
AFTER|BEFORE INSERT|UPDATE|DELETE ON 表名
[FOR EACH ROW] ---行触 发器
BEGIN
执行体;
end; ---如果有人删除emp表中的数据,给出警告信息
CREATE OR REPLACE trigger tri_demo1
AFTER DELETE ON emp
BEGIN
dbms_output.put_line('有人删除了emp表中的数据,请注意');
end; DELETE FROM emp WHERE empno=7566; CREATE OR REPLACE TRIGGER tri_demo1
AFTER DELETE or update or insert ON emp
BEGIN
IF deleting THEN
dbms_output.put_line('有人在删除emp表的数据');
elsif inserting THEN
dbms_output.put_line('有人新增了数据');
elsif updating THEN
dbms_output.put_line('有人修改了数据');
end if;
END; DELETE INSERT UPDATE
:NEW 无 有效 有效
:old 有效 无 有效 CREATE OR REPLACE TRIGGER tri_demo3
before DELETE OR UPDATE OR INSERT ON emp
for each row
BEGIN
IF deleting THEN
dbms_output.put_line('有人在删除emp表的数据');
dbms_output.put_line(:old.ename ||','||:old.sal);
elsif inserting THEN
dbms_output.put_line('有人新增了数据');
dbms_output.put_line(:new.ename ||','||:new.sal);
elsif updating THEN
dbms_output.put_line('有人修改了数据');
dbms_output.put_line('原数据为:'||:OLD.ename ||','||:OLD.sal);
dbms_output.put_line('修改后的数据为:'||:new.ename ||','||:new.sal);
END IF;
END; 语句触发器:无论增加、删除、修改多少行数据,触发器只触发一次
行触发器:增加、删除、修改对于每一行涉及的数据,触发器都会执行 INSERT INTO emp(empno,ename,sal) VALUES(1000,'bbb',6000);
commit; DELETE FROM emp WHERE deptno=10;
commit;

Oracle.PL/SQL高级的更多相关文章

  1. oracle PL/SQL高级特性

    触发器:存放在数据库中,并被隐含执行的存储过程. 由触发事件,触发条件,触发操作组成. DML触发器:指定触发器时机(before or after),触发事件(insert  , delete, u ...

  2. Oracle PL/SQL 高级编程

    1. 复合数据类型--记录类型 Ø        语法格式 type  类型名 is   record ( 字段1  字段1类型 [not null]:=表达式1; 字段2  字段2类型 [not n ...

  3. Oracle PL/SQL高级应用 存储过程

    有名字的Plsql块,成为Oracle的对象,在以后用到时可以直接调用. CREATE OR REPLACE PROCEDURE myproc(id IN varchar2) IS -IN 为输入参数 ...

  4. Oracle PL/SQL高级应用 视图 同义词 序列

    视图: 视图叫虚表,即是在哪个表上建立的视图,将那个表的数据用一条查询sql语句查出的数据展现在该视图中,对这个视图操作就是只能对该视图中的数据进行操作,该操作也会保存在建立的表中.可以理解为表上表, ...

  5. Oracle PL/SQL高级应用 游标

    游标可以处理SQL语句查询出来的结果集,进行逐条控制,其实游标在内存中申请空间,将自己指向SQL语句查询出来的结果集,有点像指针的感觉,游标使SQL更加的灵活. DECLARE CURSOR mycu ...

  6. oracle学习笔记(十七) PL/SQL高级应用

    PL/SQL高级应用 动态SQL 在PL/SQL中,不能直接执行DDL(create,alter,drop),得使用动态SQL,当然,除了DDL,动态SQL也可以执行DML(select,insert ...

  7. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  8. [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)

    原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...

  9. [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

    原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日 ...

随机推荐

  1. django序列化 serializers

    Django的序列化工具让你可以将Django的模型‘翻译’成其它格式的数据.通常情况下,这种其它格式的数据是基于文本的,并且用于数据交换\传输过程. 一.序列化数据 Django为我们提供了一个强大 ...

  2. libxml2_ZC积累

    1.Qt5.3.2(VS2010 OpenGL) 1.1.查找节点的 带NameSpace的属性 参考网址:https://stackoverflow.com/questions/7872413/ho ...

  3. vue中兄弟组件间通讯

    vue2.0中兄弟组件间的通讯是通过eventBus(事件发布订阅)实现的. eventBus.js import Vue from 'vue' const eventBus = new Vue() ...

  4. Jmeter 接口测试知识梳理——持续集成篇

    Jmeter 使用也有很长时间了,但是一直没有做一下知识梳理,近期会对公司同事做一下这方面的培训,借此机会,把使用过程中应用到的知识,或是遇到的问题,整理出来,方便大家学习! Jmeter + Ant ...

  5. Angular 学习笔记 ( timezone + moment + material date-picker + date pipe + asp.net core )

    参考 : https://stackoverflow.com/questions/29979609/time-conversion-with-timezoneinfo-for-past-years h ...

  6. C# wave mp3 播放器探寻

    C# wave mp3 播放器探寻   最近无聊,想听听歌曲.可怜新电脑上歌曲就两三首,要听其它的就得在旧电脑上播放.可是,那台古董但不失健壮的本本被老婆无情的霸占了.无奈. 思来想去,得,写个程序播 ...

  7. scrapy 爬虫框架之持久化存储

    scrapy  持久化存储 一.主要过程: 以爬取校花网为例 : http://www.xiaohuar.com/hua/ 1.  spider    回调函数     返回item 时    要用y ...

  8. css 水平垂直居中显示(定高不定高定宽不定宽)

    position 元素已知宽度 <!DOCTYPE html><html lang="en"><head> <meta charset=& ...

  9. 微信小程序 swiper 显示图片计数 当前/总数

    <view class="swiperContainer"> <swiper bindchange="swiperChange" autopl ...

  10. pytorch构建自己设计的层

    下面是如何自己构建一个层,分为包含自动反向求导和手动反向求导两种方式,后面会分别构建网络,对比一下结果对不对. -------------------------------------------- ...