使用PL-SQL
1.关于PL-SQL(功能、特点及语法结构)
2.数据类型(%type与%rowtype)
3.PL-SQL控制语句
4.异常处理
5.函数
============================================
PL/SQL是过程语言PL与结构化查询语言SQL结合而成的编程语言。
PL/SQL是针对Oracle数据库的;
它是过程语言 + 结构化查询语言的结合;过程语言PL:如变量声明,流程的控制,循环等;
查询语言SQL:SQL语言,如增、删、改、查等;
PL/SQL是SQL的扩展版,SQL能做的,PL/SQL绝大多数都能做。
PL/SQL的优点:
1.支持SQL:数据操纵命令,事务控制命令,游标控制,SQL函数和SQL运算符;
2.支持面向对象编程;
3.可移植性,可运行在任何操作系统上;
4.经过编译执行,性能佳;
5.与SQL紧密集成,简化数据处理,支持SQL数据类型,支持NULL值,支持%type和%rowtype属性类型(oracle中最有意思的);
6.安全性PL/SQL分成三个部分:
1. 声明部分
2. 可执行部分
3. 异常片理部分
语法结构:
[declare declaration] --声明部分
begin
executable statements --可执行部分
[exception handlers] --异常区
end;
输出:
select 'abc' from dual;
dbms_output.put_line('abc');--打印输出(必带begin)
begin
dbms_output.put_line('abc');
end赋值:( := )
--变量声明赋值,并打印
declare i number(6);
begin
i:=77; //:=赋值,select...into也是赋值
dbms_output.put_line(i);
end;--在emp表中将工号为7369的姓名输出
declare sid number;
sname varchar2(22);
begin
sid:=7369;
select ename into sname from emp where empno=sid; --select...into赋值方式
dbms_output.put_line(sname);
end;提示下:在begin里面用select语句,必定要用select…into。
===========================================
数据类型:
1.标量类型
2.LOB类型
3.属性类型:
%type:提供某个变量或数据库表列的数据类型
%rowtype:提供表中一行的记录类型(非常有特色)
3.1 %type--求7369的入职日期(在不知道该列是什么类型的情况下)
--申请一个与“入职日期”一样的declare sid number;
shiredate emp.hiredate%type; --声明个变量,它的类型与表中某个列的类型一样
begin
sid:=7369;
select hiredate into shiredate from emp where empno=sid;
dbms_output.put_line(shiredate);
end;--也可以sb shiredate%type;
--求某某的所有信息
declare sid number;
sname emp.ename%type;
sjob emp.job%type;
begin
sid:=7369;
select ename,job into sname,sjob from emp where empno=sid;
dbms_output.put_line(sname||' '||sjob);
end;
当然,要是表中有很多的列,还像以上这么写吗?
NO,使用行类型:%rowtype;--查询某某的所有信息
declare sid number;
er emp%rowtype;
begin
sid:=7369;
select * into er from emp where empno=sid;
dbms_output.put_line(er.ename||' '||er.job);
end;
============================================输入:& (一般做测试用,其它情况不怎么用)
declare sid number;
er emp%rowtype;
begin
sid:=&请输入; --&类似scanner
select * into er from emp where empno=sid;
dbms_output.put_line(er.ename||' '||er.job);
end;注意:sid:=&请输入; --代表录入的是整型
sid:='&请输入'; --代表录入的是varchar2类型。
=======================================
逻辑比较:
<> , !========================================
控制语句:
if 条件 then
……
else或者elsif…then
……
end if--工资大于3500交税,=3500刚好,<3500努力
if语句:
begin
if sal>3500 then
dbms_output.put_line('交税');
elsif sal=3500 then
dbms_output.put_line('刚好');
else
dbms_output.put_line('努力');
end if;
end;
case语句:
case
when then ;
when then ;
else
end case;循环语句:有三种:
1.loop 无条件循环
2.while
3.for--打印1~100
declare i number;
begin
i:=1;
loop
dbms_output.put_line(i);
i:=i+1;
exit when i=100; --退出及退出条件
end loop;
end;
============================================
declare i number;
begin
i:=1;
<<b_loop>> --loop循环的名字
loop
dbms_output.put_line(i);
i:=i+1;
exit b_loop when i=100; --退出及退出条件
end loop;
end;
==========================================
--求1~100的和
declare i number;
mysum number;
begin
i:=0;
mysum:=0;
while i<=100 loop
mysum:=mysum+i;
i:=i+1;
end loop;
dbms_output.put_line('总和:'||mysum);
end;
--循环里都会使用到loop--for循环的写法:
declare
mysum number;
begin
mysum:=0;
for i in 1..100 loop
mysum:=mysum+i;
end loop;
dbms_output.put_line(mysum);
end;
--求奇数之和
declare
mysum number;
begin
mysum:=0;
for i in 1..100 loop
if mod(i,2)=1 then
mysum:=mysum+i;
end if;
end loop;
dbms_output.put_line(mysum);
end;
--顺序语句:goto 标名……<<标名>>
不讲,不用了。======================================
异常:
1.系统自带的异常---预定义异常
2.我们写代码报的异常---自定义异常1.预定义异常
too_many_rows : 行太多
no_data_found : 数据未找到例示:预定义异常:
declare sid number;
shiredate emp.hiredate%type;
sb shiredate%type;
begin
sid:=7369;
select hiredate into shiredate from emp;
dbms_output.put_line(shiredate);
--异常
exception --发生异常就会报错
when too_many_rows then
dbms_output.put_line('行太多');
end;例示:自定义异常
三步:声明,判断,捕捉iee exception;
raise iee;
exception when iee then
dbms_output.put_line('错误信息');
when too_many_rows then
dbms_output.put_line('错误信息');
……可以带多个异常体
===============================================
函数:
create or replace function f_name [(参数1,参数2..)]
return 类型
is/as
[local declarations] --函数体里面的变量声明全放该位置begin
--执行体
return
--异常
end;
--案例:给编号,返回工资'交税'还是'刚好',还是'努力'
create or replace function f_n126(sid number)
return varchar2
isssal number(8,2);
str varchar2(22); --注意,该处不用declare定义begin
select sal into ssal from emp where empno=sid;
if ssal>3500 then
str:='交税';
elsif ssal=3500 then
str:='刚好';
else
str:='努力';
end if;
return str;
end;--如何调用函数?
--oracle调用方式:
select f_n126(7369) from dual;
--pl/sql调用方式:
declare str varchar2(22);
begin
str:=f_n126(7369);
dbms_output.put_line(str);
end;======自定义异常=========================================
declare n_s number(5);
e_my exception;
pragma exception_init(e_my,-20001);
begin
select count(stuname) into n_s from stuinfo where stuname like '赵%';
if n_s=0 then
raise e_my;
end if;
dbms_output.put_line('数量是'||n_s);exception
when e_my then
dbms_output.put_line('人员为空');
end;
=====函数=================================================
create or replace function my_temp(n_s in varchar2, n_max in out number)
return number is
n_tavg number(5, 2);
begin
select avg(stuage),max(stuage) into n_tavg,n_max from stuinfo where stuname like n_s||'%';
return n_tavg;
end;create or replace function my_sum(n_a in number)
return number
is
n_sum number(5):=0;
beginfor int_s in 1..n_a loop
n_sum:=n_sum+int_s;
end loop;
return n_sum;
end;
演示基本用法
--oracle-03 内置函数
--转换函数:to_date to_char to_number
--日期函数:sysdate|systimestamp|add_months|months_between|extract(year from sysdate)|last_day|next_day|round|trunc
--字符串函数:lower|upper|ltrim|rtrim|lpad|rpad|chr|ascii|instr|substr|replace|decode|length
--数学函数:abs|round|trunc|sign|mod|power|sqrt|ceil|floor
-----------------------------------------------------------------------
--oracle-04 PL/SQL编程
1.pl:过程语言
2.sql:结构化查询语言
3.pl/sql 是过程语言与结构化查询语言的结合。sql语言能实现的 pl/sql也能实现。
4.pl/sql编程中包含哪些技术?
打印输出,变量使用,选择结构,循环结构
5.pl/sql组合:三部分组合
(1)声明(定义)部分
(2)可执行部分
(3)异常处理部分(在可执行部分中包裹)
其中第二个模块是必须的,而第一个和第三个是可选(根据需求而定)
6.语法
declare--声明部分
属性名 属性类型;
....
begin---可执行部分的开始位置
利用sql语句执行得到的结果集可以通过特定方式将结果赋值给上面declare所定义的变量中.
异常处理部分
end;---可执行部分的结束位置
select sal from emp where empno = 7369;
--需求:通过PL/SQL编程打印输出"zz is a nice man"
--打印输出:dbms_output.put_line();---》来源与oracle中的内置程序包
begin
dbms_output.put_line('zz is a nice man');
end;
--定义一个变量保存一个姓名,然后打印输出
declare
sname varchar2(50);
begin
--变量的赋值:=
sname := '张三';
dbms_output.put_line(sname);
end;
-----------------------------------------------
declare
sname varchar2(50):='里斯';
begin
dbms_output.put_line(sname);
end;
-----------------------------------------------
--定义多个变量
declare
sname varchar2(50):='里斯';
ssex varchar2(2):='男';
begin
dbms_output.put_line('我的姓名是:'||sname||',我的性别是: '||ssex);
end;
--oracle中的输入器 & 包裹在单引号中。
declare
sname varchar2(50):='&请输入';
ssex varchar2(2):='男';
begin
dbms_output.put_line('我的姓名是:'||sname||',我的性别是: '||ssex);
end;
--打印输出7499的薪水。
declare
myempno number:=7499;
mysal number;
begin
--语法: select aa into bb from 表
select sal into mysal from emp where empno = myempno;
dbms_output.put_line('薪水为: '||mysal);
end;
--打印输出7369的姓名以及薪水
declare
myempno number:=7369;
myename varchar2(100);
mysal number;
begin
--语法: select aa into bb from 表
select ename,sal into myename,mysal from emp where empno = myempno;
dbms_output.put_line('薪水为: '||mysal||' '||myename);
end;
-----------------------------------------------------------------
PL/SQL编程中的2个重要类型
属性类型 %type
行类型 %rowtype 相当于oop的对象
--打印输出7369的薪水(不确定类型)
declare
myempno emp.empno%type:=7369; ------- emp.empno%type => number
mysal emp.sal%type;
begin
select sal into mysal from emp where empno = myempno;
dbms_output.put_line(mysal);
end;
--打印输出7369的全部属性
declare
myempno emp.empno%type:=7369; ------- emp.empno%type => number
myemp emp%rowtype;
begin
select * into myemp from emp where empno = myempno;
dbms_output.put_line(myemp.empno||' '||myemp.ename||' '||myemp.sal);
end;
-------------------------------------------------------------
#选择结构 if case
--需求:判断一个数字是否为偶数
declare
mynum number:=10;
begin
if (mod(mynum,2)=0) then
dbms_output.put_line('偶数');
else
dbms_output.put_line('奇数');
end if;--结束选择结构
end;
-->3000 纳税 =3000 继续努力 <3000 回家养猪
select ename,sal,
decode(sign(sal-3000),'1','纳税','0','继续努力','-1','回家养猪')
from emp;
--没有学习游标(课件) 只能查询一个
--判断7369处于哪个级别
declare
myempno emp.empno%type:=7369;
mysal emp.sal%type;
begin
select sal into mysal from emp where empno = myempno;
--拿到mysal进行判断即可
if (mysal > 3000) then
dbms_output.put_line('纳税');
elsif (mysal = 3000) then
dbms_output.put_line('继续努力');
elsif(mysal < 3000) then
dbms_output.put_line('回家养猪');
end if;
end;
--case end case
begin
case 'F'
when 'A' then dbms_output.put_line('优秀');
when 'B' then dbms_output.put_line('良好');
when 'C' then dbms_output.put_line('一般');
when 'D' then dbms_output.put_line('还好咯');
else
dbms_output.put_line('LOW');
end case;
end;
------------------------------------------------------
--loop while for
--loop循环
/*
loop
end loop;
与java中的死循环一致 while(true){}
*/
declare
mynum number:=1;
begin
loop
dbms_output.put_line(mynum);--99
mynum:=mynum+1;
exit when mynum = 101;
end loop;
end;
--1-100的和
declare
mynum number:=1;
mysum number:=0;
begin
loop
mysum:=mysum + mynum;
mynum:=mynum+1;
exit when mynum = 101;
end loop;
DBMS_OUTPUT.PUT_LINE(mysum);
end;
--命名
declare
mynum number:=1;
mysum number:=0;
begin
<<myloop>>
loop
mysum:=mysum + mynum;
mynum:=mynum+1;
exit when mynum = 101;
end loop;
DBMS_OUTPUT.PUT_LINE(mysum);
end;
--while循环
declare
mynum number:=1;
begin
while (mynum<=100) loop
dbms_output.put_line(mynum);
mynum:=mynum+1;
end loop;
end;
--for循环最简洁
begin
for i in 1..100 loop
dbms_output.put_line(i);
end loop;
end;
--异常
1.预设义异常:系统给定 no_data_found(未找到数据异常) too_many_rows(行太多异常)
2.自定义异常:raise抛出异常
(1)定义自定义异常 exception
(2) 根据需求判断后抛出异常 raise
(3)捕捉该异常 exception
declare
myempno number:=123;
mysal number;
begin
--语法: select aa into bb from 表
select sal into mysal from emp where empno = myempno;
dbms_output.put_line('薪水为: '||mysal);
exception
when no_data_found then
dbms_output.put_line('未找到数据异常(提供的编号不存在)');
end;
--------------------
declare
mysal number;
begin
--语法: select aa into bb from 表
select sal into mysal from emp;
dbms_output.put_line('薪水为: '||mysal);
exception
when too_many_rows then
dbms_output.put_line('行太多异常');
when no_data_found then
dbms_output.put_line('未找到数据异常');
end;
--查询指定编号的薪水,如果不在2000-5000之间,抛出自定义异常
declare
myempno emp.empno%type:=7369;
mysal emp.sal%type;
myExceptionSal exception;
begin
select sal into mysal from emp where empno = myempno;
if (mysal < 2000 or mysal > 5000) then
--抛出异常
raise myExceptionSal;
end if;
exception
when myExceptionSal then
dbms_output.put_line('未薪水不在指定的范围异常');
end;
------------------------------------------------------------------
--函数 function 作用:一次封装多次利用
/*
public void add(){
}
create or replace function 函数名称(参数列表)
return 返回类型
as|is
声明部分
可执行部分
*/
--封装函数 根据指定的编号查找薪水
create or replace function getSalById(myempno emp.empno%type)
return emp.sal%type
as
mysal emp.sal%type:=0;
begin
select sal into mysal from emp where empno = myempno;
return mysal;
end;
--调用函数
select getSalById(7369) from dual;
--1-100的和
create or replace function mySum(mynum number)
return number
as
sums number:=0;
begin
for i in 1..mynum loop
sums:=sums + i;
end loop;
return sums;
end;
select mySum(10) from dual;
-- 递归实现斐波那契数列的第21项的那个数字
-- 1 1 2 3 5 8 13 21 .......
create or replace function diGuiDemo(mynum number)--3 diGuiDemo(1)+diGuiDemo(2)
return number
as
begin
if( mynum = 1 or mynum = 2) then
return 1;
else
return diGuiDemo(mynum-1)+diGuiDemo(mynum-2);
end if;
end;
select diGuiDemo(21) from dual;