1. 程序结构:
-- 声明部分
declare
-- 声明变量 游标等
-- 程序开始
begin
--程序体
-- 程序结束
end;
/
2. 打开屏幕输出开关
set serveroutput on
3. 声明变量(在declare部分):
3.1. 变量名 类型(长度);
example varchar2(30);
可以直接赋值。
example number := 38;
3.2 变量名 表名.字段%type;
example dept.deptno%type;
注意:引用类型变量引用某个表具体字段类型和长度,比较灵活,缺点是不易读,赋值一旦超出类型长度,将会报错,具体长度受源表字段影响。超出后报"ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小"
3.3 记录型变量 变量名 表名%rowtype;
emp_rec emp%rowtype;
-- 赋值:
select * into emp_rec from emp where empno = 7839;
--取值:
dbms_output.put_line(emp_rec.empno || emp_rec.ename);
4. 变量赋值(在begin内部):
4.1 变量名 := 具体值;
example := 'hello world';
4.2 通过SQL语句赋值
select deptno into example from dept d where d.deptno = 20;
注意:查到结果集要和变量匹配,假如查到多行数据,赋值给一行,将会报"ORA-01422: 实际返回的行数超出请求的行数"
5. 打印语句
dbms_output.put_line(打印内容或变量);
连接使用 "||"
6. if语句
SET SERVEROUTPUT ON
ACCEPT NUM PROMPT '请输入一个数字';
DECLARE
pnum NUMBER := #
BEGIN
IF pnum = 0 THEN dbms_output.put_line('刚才输入的数字是0');
ELSIF pnum = 1 THEN dbms_output.put_line('刚才输入的数字是1');
ELSE dbms_output.put_line('刚才输入的数字是' || pnum);
END IF;
END;
/
以IF 表达式 THEN 具体语句,可以有多条;
ELSIF 表达式 THEN 具体语句;
ELSE 语句;
END IF;
7. 循环
set serveroutput on
declare
pnum number := 1;
begin
-- 循环输出1到10
while pnum <= 10 loop
dbms_output.put_line(pnum);
-- 变量加1
pnum := pnum +1;
end loop;
end;
/
推荐使用下面这种循环,方便控制游标
set serveroutput on
declare
pnum number := 1;
begin
-- 循环输出1到10
loop
-- 当表达式满足时,不在进行循环
exit when pnum = 10 ;
dbms_output.put_line(pnum);
-- 变量加1
pnum := pnum +1;
end loop;
end;
/
for循环:
SET SERVEROUTPUT ON
DECLARE
pnum NUMBER := 1;
BEGIN
-- 循环输出1到10
FOR I IN 1..10 LOOP
dbms_output.put_line(pnum);
-- 变量加1
pnum := pnum +1;
END LOOP;
END;
/
1...10 代表1到10
8. 游标(光标)
set serveroutput on
declare
cursor cemp is select ename,sal from emp;
pename emp.ename%type;
psal emp.sal%type;
begin
-- 打开游标
open cemp;
loop
fetch cemp into pename,psal;
-- 当表达式满足时,不在进行循环
exit when cemp%notfound;
dbms_output.put_line(pename || '的薪水是' || psal);
end loop;
-- 关闭游标,释放资源
close cemp;
end;
/
注意:fetch语句位于loop下一行,如果位于exit when下面,循环多执行一次。 10,20,30,40,40
先打开光标,然后loop,取出光标,设置结束条件,具体代码,结束循环,关闭游标。
9. 异常
SET SERVEROUTPUT ON
DECLARE
pnum NUMBER;
pname emp.ename%TYPE;
cursor cemp is select ename from emp where empno = 555555;
no_emp_found exception;
BEGIN
-- 1. zero_divide
--pnum := 3 / 0;
-- 2. value_error
--pnum := 'rrrr';
-- 3. too_many_rows
--select ename into pname from emp;
-- 4. no_data_found
--select ename into pname from emp e where E.empno = 62155555553;
OPEN cemp;
FETCH cemp INTO pname;
IF cemp%notfound THEN
dbms_output.put_line('--cemp not found');
-- 5. user define exception
raise no_emp_found;
END IF;
IF cemp%notfound THEN
CLOSE cemp;
END IF;
EXCEPTION
WHEN zero_divide THEN
dbms_output.put_line('--zero');
WHEN value_error THEN
dbms_output.put_line('--value error');
WHEN too_many_rows THEN
dbms_output.put_line('--too many rows');
WHEN no_data_found THEN
dbms_output.put_line('--no data found');
WHEN no_emp_found THEN
dbms_output.put_line('-- user exception');
WHEN OTHERS THEN
dbms_output.put_line('--others exception');
END;
/
来源:oschina
链接:https://my.oschina.net/u/3309981/blog/1629056