PL/SQL概述
PL/SQL(Procedureal Language/SQL,过程化SQL语言)在标准SQL语言下发展起来的。
PL/SQL语言将变量、控制结构、过程和函数等结构化程序设计的要素引入到SQL语言中。
特点是:
- 具有模块化的结构
- 使用过程化语言控制结构
- 能够进行错误处理
是一个块结构,划分为:变量定义、逻辑处理、异常处理 三块
PL/SQL语法
声明变量
- 由DECLARE关键字开始
- BEGIN程序体结束
- 强类型语言
- 举例代码如下:
Declare
v_id integer;
v_name varchar(20);
begin
Varriable_name [CONSTANT] databyte
[NOT NULL] [:=|DEFAULT expression]
- 如果有了NOT NULL约束条件,则初始化必须赋值
- 直接赋值
- 通过SQL SELECT INTO或FETCH INTO给变量赋值
表达式
declare
result number;
begin
result:=10+3*4+40;
dbms_output.put_line('result:'||result);
end;
执行结果为:
result:62
PL/SQL过程已成功完成。
Dbms_output.put_line函数是输出后换行,put是输出不换行
PL/SQL程序块结构
- 声明部分(declarative section)
- 执行部分(executable section)
- 异常处理部分(exception section)
Declare
声明部分
Begin
执行部分
Exception
异常执行部分
End ;
注释:
- 单行注释(–),多行注释(/ * * /)
标识符:
- 由一个字母开始,后面选折性地跟随任意多的字母,数字,货币符号($),下划线(_),#等符号组成.不允许使用空格,斜线(/),短横线(-),&,%. 最大长度为30个字符.
字符集:
- 大写字母A-Z和小写字母a-b
- 数字0-9
- 符号(,),+,-,*,/,<,>,=,!,~,^,;,:,.,’,@,”,#,$,_,|,{,},?,[,]
- 制表符,空格符,回车符等非显示的间空符号.
- 其中一些字符用于编程,另外一些用做算术运算符或关系运算符
代码示例:
declare
v_checkout timestamp(6);
begin
v_checkout:=sysdate;
dbms_output.put_line(v_checkout);
end;
declare
v_lifetime interval year(4) to month;
aa date;
begin
v_lifetime := interval '0001-3' year to month;
select sysdate+v_lifetime into aa from dual;
dbms_output.put_line(aa);
end;
PL/SQL运行环境
- SQL*PLUS
- TOAD
- PL/SQL Developer
PL/SQL数据类型
- Boolean+
- %type+
- %rowtype+
- %record+
- table
%type
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
c_tax_rate constant number(3,2) :=0.03;
v_sal_tax v_sal%type;
begin
select ename,sal into v_ename,v_sal from emp
where empno=&eno;
v_sal_tax := v_sal * c_tax_rate;
dbms_output.put_line('雇员名字:'||v_ename);
dbms_output.put_line('雇员薪水:'||v_sal);
dbms_output.put_line('雇员所得税:'||v_sal_tax);
end;
%rowtype
declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno=&eno;
dbms_output.put_line('雇员名字:'||v_emp.ename);
dbms_output.put_line('雇员薪水:'||v_emp.sal);
dbms_output.put_line('雇员工种'||v_emp.job);
end;
table
--类似于数组
--定义的语法 type table_type is table of data_type index by binary_integer;
declare
type emp_table_type is table of emp.ename%type index by binary_integer;
emp_table emp_table_type;
begin
select ename into emp_table(-1) from emp where empno=&eno;
emp_table(0):='jack';
emp_table(1):='lucy';
dbms_output.put_line('emp_table(-1)雇员名:'||emp_table(-1));
dbms_output.put_line('emp_table(0):'||emp_table(0));
dbms_output.put_line('emp_table(1)'||emp_table(1));
end;
--这个是数字类型的数组了。
DECLARE
TYPE numberarray IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
firstnumber numberarray;
secondnumber numberarray;
BEGIN
firstnumber(0) :=123456;
firstnumber(1) := 888888;
secondnumber(0) := 222222;
secondnumber(1) := 666666;
FOR i IN 0..firstnumber.count -1 LOOP
DBMS_OUTPUT.PUT_LINE('i='|| i || ', firstnumber[0]= ' ||firstnumber(i)|| ',
secondnumber= ' ||secondnumber(i));
END LOOP;
END;
PL/SQL流程控制
条件控制
语法:
IF condition1 THEN
statements1
ELSIF condition2 THEN
statements2
ELSE
statements3
END IF;
declare
v_sal number(7,2);
begin
select sal into v_sal from emp where ename='SCOTT';
dbms_output.put_line('scott salary:'||v_sal);
if v_sal<100 then
dbms_output.put_line('scott 工资低于1000');
else
if 1000<=v_sal and v_sal<2000 then
dbms_output.put_line('scott1在1000到2000之间');
else
dbms_output.put_line('scott1工资高于2000');
end if;
end if;
end;
CASE 结构
CASE
WHEN 条件表达式1 THEN
语句段1
WHEN 条件表达式2 THEN
语句段2
……
ELSE
语句段N
END CASE;
declare
v_sal number(7,2);
begin
select sal into v_sal from emp where ename='SCOTT';
dbms_output.put_line('scott工资:'||v_sal);
case
when v_sal<1000 then
dbms_output.put_line('scott工资低于1000');
when 1000<=v_sal and v_sal<2000 then
dbms_output.put_line('scott工资在1000到2000之间');
else
dbms_output.put_line('scott工资高于2000');
end case;
end;
declare
v_grade char:='a';
begin
case v_grade
when 'a' then
dbms_output.put_line('excellent');
when 'b' then
dbms_output.put_line('very good');
when 'c' then
dbms_output.put_line('good');
else
dbms_output.put_line('no such grade');
end case;
end;
循环控制
- 简单循环
须显示结束循环 - while 循环
直到条件不满足时结束循环 - for 循环
循环预先确定的次数
简单循环
[<<循环标签>>]
LOOP
statement
END LOOP [循环标签];
跳出循环:
EXIT [循环标签]
EXIT [循环标签] WHEN 条件表达式
declare
v_i number:=1;
v_s number:=0;
begin
loop
exit when v_i>100;
v_s:=v_s+v_i;
v_i:=v_i+1;
end loop;
dbms_output.put_line(v_s);
end;
while 循环
[<<循环标签>>]
WHILE 条件表达式 LOOP
语句段
END LOOP [循环标签];
declare
v_i number:=1;
v_s number:=0;
begin
while v_i<=100 loop
v_s:=v_s+v_i;
v_i:=v_i+1;
end loop;
dbms_output.put_line(v_s);
end;
for 循环
[<<循环标签>>]
FOR 循环变量 IN [REVERSE] 初始表达式..终值表达式 LOOP
语句段
END LOOP [循环标签];
declare
v_s number:=0;
begin
for v_i in 1..100 loop
v_s:=v_s+v_i;
end loop;
dbms_output.put_line(v_s);
end;
循环嵌套
WHILE 条件1 LOOP
语句段11
WHILE 条件2 LOOP
语句段2
END LOOP;
语句段12
END LOOP;
循环嵌套
LOOP
语句段11
WHILE 条件1 LOOP
语句段2
END LOOP;
语句段12
EXIT WHEN 条件2
END LOOP;
顺序控制
语法:
GOTO 标签
NULL 语句
语法:
NULL
(表示什么也不执行)
declare
v_i number:=0;
v_s number:=0;
begin
<<label_1>> v_i:=v_i+1;
if v_i<=100 then
v_s:=v_s+v_i;
goto label_1;
end if;
dbms_output.put_line(v_s);
end;
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
v_empno:=&emp_no;
select ename,sal into v_ename,v_sal from emp where empno=v_empno;
if v_sal<=3000 then
update emp set comm=v_sal*01 where empno=v_empno;
dbms_output.put_line(v_ename||'补助'||v_sal*0.1);
else
null;
end if;
end;