pl/sql 的概念
1、结构化查询语言(Structured Query Language,简称SQL)是用来访问关系型数据库一种通用语言,其执行特点是非过程化,不需要用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,即不用指明执行的具体方法和途径,而是简单的调用相应语句来直接取得结果即可。
2、pl/sql不仅仅是一个数据库查询语言,而且也是一个编程语言。PL/SQL 是过程化语言,对SQL的补充,可以用来实现比较复杂的业务逻辑。
3、T-SQL是Transact-SQL,是微软对SQL的扩展,具有SQL的主要特点,同时增加了变量、运算符、函数、流程控制和注释等语言元素,使得其功能更加强大。
Transact-SQL 是具有批量与区块特性的SQL指令合集,数据库开发人员可以利用他来撰写数据部分的商业逻辑(Data-based Business Logic),以强制限制前端应用程序对数据的控制能力。
同时,他也是数据库对象的主要开发语言。
一、语法结构
declare 声明变量----必须一行一个变量用分号结束每一行声明 ;
begin
SQL语句
PL/SQL控制语句
exception
错误发生时执行的动作
end;
例题:打印系统当前日期
declare
current_date date:=sysdate;--一行只能有一个变量必须以分号结尾
begin
dbms_output.put_line(current_date);
end;
二、变量的使用
1、type --不知道数据类型(V_表示变量的意思)
declare
v_empename emp.ename%type;
begin
select ename into v_empename from emp where empno=7788;
dbms_output.put_line(v_empename);
end;
例题:查询
declare
v_empno emp.empno%type;
begin
select empno into v_empno from emp where ename='SCOTT';
dbms_output.put_line(v_empno||' '||'SCOTT');
end;
2、rowtype --整张表都不知道数据类型
例题:打印员工编号为7788的姓名,雇佣日期
declare
v_a emp%rowtype;
begin
select * into v_a from emp where empno=7788;
dbms_output.put_line(v_a.empno||' '||v_a.ename||' '||v_a.hiredate);
end;
例题:使用PL/SQL显示员工编号为7788的员工编号,姓名,雇用日期,部门名称。
显示格式例如:员工编号:7788,姓名:SCOTT,雇用日期:1978-03-21,部门:RESEARCH。
declare
v_e emp%rowtype;
v_d dept%rowtype;
begin
select * into v_e from emp where empno=7788;
select * into v_d from dept where deptno=( select deptno from emp where empno=7788);
dbms_output.put_line('员工编号:'||v_e.empno||', 姓名:'||v_e.ename||', 雇佣日期:'||to_char(v_e.hiredate,'yyyy-ww-dd')||', 部门:'||v_d.dname||'。');
end;
例题:输出姓名为SMITH 的员工编号,工作,工资。
declare
v_a emp%rowtype;
begin
select * into v_a from emp where ename='SMITH';
dbms_output.put_line(v_a.empno||' '||v_a.job||' '||v_a.sal);
end;
3、变量的初始化
(1)constant 用在数据类型前不能进行第二次赋值
(2)not null 用在数据类型后必须要给赋值
declare
v_a constant number(10) :=10;
v_b number not null :=0;
begin
(错误,不能赋值)
dbms_output.put_line(v_a);
dbms_output.put_line(v_b);
end;
4、变量的赋值
变量赋值有两种方法:(1)使用“:=”
(2)select ... into :查询结果赋值给变量、
有多个字段的查询结果赋值给多个变量
整行数据赋值
三、分支循环控制语句
1、三种条件分支结构
(1)if then
declare
v_a number(5):=9;
begin
if v_a<10 then
dbms_output.put_line('我爱睡觉');
end if;
end;
(2)if then ; else
declare
v_a number(5) := 9;
begin
if v_a > 10 then
dbms_output.put_line('我爱睡觉');
else
dbms_output.put_line('我爱吃芒果');
end if;
end;
(3)if then ; elsif then; else
declare
v_a number(5) := 6;
begin
if v_a > 10 then
dbms_output.put_line('我爱睡觉');
elsif v_a<10 then
dbms_output.put_line('我爱吃火锅');
elsif ... then ...
...
else
dbms_output.put_line('我爱吃芒果');
end if;
end;
例题:给员工加薪水,加薪规则如下:
create table myemp as select * from emp
declare
v_sal myemp.sal%type;
begin
select avg(sal) into v_sal from myemp;
if v_sal<=1000 then
update myemp set sal=sal*1.2;
elsif v_sal>1000 and v_sal<=2000 then
update myemp set sal=sal*1.15;
elsif v_sal>2000 and v_sal<=3000 then
update myemp set sal=sal*1.1;
else
update myemp set sal=sal*1.05;
end if;
end;
select * from myemp
2、三种循环结构
(1)基本循环
declare
v_a number(2):=0;
begin
loop
v_a:=v_a+1;
exit when v_a>3;
end loop;
dbms_output.put_line(v_a);
end;
2、while_loop 循环
declare
v_a number(2):=0;
begin
while v_a<=3
loop
v_a:=v_a+1;
end loop;
dbms_output.put_line(v_a);
end;
3、for_loop 循环
例题:输出1..10 相加结果
declare
v_a number(2):=1;
v_sum number(2):=0;
begin
for v_a in 1..10
loop
v_sum:=v_sum+v_a;
end loop;
dbms_output.put_line(v_sum);
end;
例题:向部门表dept1中插入10条数据,部门编号从41到50。部门名称分别是dept41,dept42,…,dept50。
create table dept1 as select * from dept
declare
dept1 dept%rowtype;
begin
for v_a in 41..50
loop
insert into dept1 (deptno,dname)
values(v_a,'dept'||v_a);
end loop;
end;
select * from dept1
declare
dept1 dept%rowtype;
v_a number:=51;
begin
loop
v_a:=v_a+1;
exit when v_a>60;
insert into dept1(deptno,dname)
values(v_a,'dept'||v_a);
end loop;
end;
declare
dept1 dept%rowtype;
v_a number:=61;
begin
while v_a<70 loop
v_a:=v_a+1;
insert into dept1(deptno,dname)
values(v_a,'dept'||v_a);
end loop;
end;
四、游标
其定义为:用游标来指代一个DML SQL操作返回的结果集。即当一个对数据库的查询操作返回一组结果集时,用游标来标注这组结果集,以后通过对游标的操作来获取结果集中的数据信息。
优点:(了解)
1 对从表中检索出的数据进行操作非常灵活。
2 允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作。
3 提供对基于游标位置而对表中数据进行删除或更新的能力。
缺点:
1 游标速度较慢。
2 处理大数据量时,效率低下,占用内存大
例题:查询emp表中empno和相对应的ename
1、显性游标---有明确的游标声明和操作过程。操作过程包括打开游标,取值,关闭游标。(loop循环)
Declare--loop循环
v_empno number(5);
v_ename varchar2(20);
cursor c_a is select empno,ename from emp;
begin
open c_a;
loop
fetch c_a into v_empno,v_ename;
exit when c_a%notfound;
dbms_output.put_line(v_empno||v_ename);
end loop;
close c_a;
end;
Declare----while循环
v_empno number(4);
v_ename varchar2(20);
Cursor c_emp is select empno, ename from emp;
Begin
open c_emp;
fetch c_emp into v_empno, v_ename;
while c_emp%found loop
dbms_output.put_line(v_empno ||' '||v_ename );
fetch c_emp into v_empno, v_ename;
end loop;
close c_emp;
End;
特例,for 循环,不用打开和关闭游标
2、隐性游标----没有明确的游标声明和操作过程。
对于非查询语句,如修改、删除操作,则由ORACLE 系统自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐性游标。在隐性游标的工作区中,所存放的数据是与用户自定义的显示游标无关的、最新处理的一条SQL 语句所包含的数据。
insert、update、delete、以及由 select into 所影响的行,都有隐性游标。
declare
v_a emp%rowtype;
cursor c_a is select empno,ename from emp;
begin
for v_a in c_a
loop
dbms_output.put_line(v_a.empno||v_a.ename);
end loop;
end;
3、游标的属性
显性游标
(1)%notfound 属性。当最近一次读记录(fetch),成功取到值,此数据为
(2)%found 属性,与 %notfound 相反
(3)%rowcount 属性, 返回由 insert、update 或 delete 所影响的行数
对于游标,则 %rowcount 表示FETCH成功的数据条数。如果 open 游标,但没有进行 fetch,则 rowcount 值为0
(4)%isopen 属性,当游标已打开时返回
隐性游标
(1)%notfound 属性
(2)%found 属性
(3)% rowcount 属性
(4)%isopen 属性(总是 false)
五、异常 exception
异常情况处理(exception)是用来处理正常执行过程中出现未预料的错误事件,使得程序遇到错误能继续运行。
常见异常名称:
相除
方法一:
declare
v_a number:='&请输入v_a';
v_b number:='&请输入v_b';
v_c number;
begin
v_c:=v_a/v_b;
dbms_output.put_line(v_c);
exception
when ZERO_DIVIDE then
dbms_output.put_line('fff');
end;
方法二:
declare
v_a number:='&请输入v_a';
v_b number:='&请输入v_b';
v_c number;
begin
v_c:=v_a/v_b;
dbms_output.put_line(v_c);
exception
when others then
dbms_output.put_line('fff');
end;
相加
declare
v_a number:='&请输入v_a';
v_b number:='&请输入v_b';
v_c number;
begin
v_c:=v_a+v_b;
dbms_output.put_line(v_c);
exception
when others then
dbms_output.put_line(777);
end;
















