(18)PL/SQL
PL/SQL(Procedure Language/SQL)
PL/SQL是Oracle对sql语言的过程化扩展---指在sql命令语言中增加了过程处理语句(如分支、循环等),使sql语言具有过程处理能力
在sqlplus中执行一下操作
set serveroutput on; --打开sqlplus的输出功能
一、一个完整的格式
1.只有执行体部分的结构,也就是只有begin ...end 部分
begin
dbms_output.put_line('');
end;
/
运行后
斜杠 / 就是让服务器执行前面所写的 SQL 脚本。 因为你普通的 select 语句, 一个分号,就可以执行。
但是如果你的是存储过程, 那么遇到分号,就不能马上执行。 这个时候,就需要通过 斜杠 来执行
2.包含声明和执行体两部分的结构
declare
v_result number(8,2);
begin
v_result :=100/6;
dbms_output.put_line('最后的结果是'||v_result );
end;
/
第一行声明变量关键字
第二行声明变量
二、注释
单行注释用 --
多行注释用 /**/
三、字符命名规则
PLSQL能用的字符集包括
1.大小写字母A-Z,a-z
2.数字0-9
3.Tab、空格、回车
4.数学符号:+,-,*,/,<,>
5.(),{},[],?,!,;,:,@,#,%,$,&
其他的字符都是非法字符(除引号里)
四、基本数据类型
定义变量时 变量名在前,数据类型在后
1.数值类型
number,pls_integer,binaru_integer
Number类型可以存储整数或浮点数;
例:Num number(9,2)
其中9表示精度,从左边不是零数到小数点后一共有9位,2表示小数点最多两位。这个区间内的的数值都是符合的
2.字符类型
varchar2,char,long,nchar,nvarchar2
name varchar2(80) --可变字符串,最大长度4000.
3.日期类型
例: pdate date;
4.布尔类型
boolean
变量的赋值要用:=
例: b boolean:=True;
declare
count number(5,2);
name varchar2(20);
today date;
begin
--赋值
count :=1
name :='hello';
today:=sysdate;
--打印
dbms_output.put_line(count);
dbms_output.put_line(name);
dbms_output.put_line(today);
end;
/
5.特殊数据类型
(1)引用型变量
name emp.ename%type; --把员工表中ename的类型 定义为name的类型
declare
name emp.ename%type;
salary emp.sal%type;
begin
--查询出emp表姓名和薪水,并用into赋值给name和salary变量
select ename,sal into name ,salary from emp where empno=7839;
dbms_output.put_line(name ||'的薪水是'||salary );
end;
/
(2)记录型变量
取一行变量的类型
declare
emp_rec emp%rowtype;
begin
--查询后把正行的变量名和类型都赋值给emp_rec
select * into emp_rec from emp where empno=7839;
dbms_output.put_line(emp_rec.ename||'的薪水是'||emp_rec.sal);
end;
/
五、流程控制语句
选择语句(包括4种)
1、 if then
只做一种条件判断
/* Formatted on 2017/5/20 9:19:56 (QP5 v5.227.12220.39754) */
set serveroutput on
DECLARE
name1 VARCHAR (50);
name2 VARCHAR (50);
BEGIN
name1 := 'abc';
name2 := 'abcd'; IF LENGTH (name1) < LENGTH (name2)
THEN
DBMS_OUTPUT.put_line ('name1的长度小于name2');
END IF;
END;
/
if条件可判断是否为空或 and or not 等逻辑运算
set serveroutput on
DECLARE
name1 VARCHAR (50);
name2 VARCHAR (50);
BEGIN
name1 := ''; IF name1 is not null
THEN
DBMS_OUTPUT.put_line ('name1不为空');
else
DBMS_OUTPUT.put_line ('name1为空');
END IF;
END;
/
2. if then else
两种判断
set serveroutput on
DECLARE
name1 VARCHAR (50);
name2 VARCHAR (50);
BEGIN
name1 := 'abcde';
name2 := 'abcd'; IF LENGTH (name1) < LENGTH (name2)
THEN
DBMS_OUTPUT.put_line ('name1的长度小于name2');
else
DBMS_OUTPUT.put_line ('name1的长度大于name2');
END IF;
END;
/
3. if then elsif
多分支判断
DECLARE
month INT := 10;
BEGIN
IF month >= 1 AND month <= 3
THEN
DBMS_OUTPUT.put_line ('春天');
ELSIF month >= 4 AND month <= 6
THEN
DBMS_OUTPUT.put_line ('夏天');
ELSIF month >= 7 AND month <= 9
THEN
DBMS_OUTPUT.put_line ('秋天');
ELSIF month >= 10 AND month <= 12
THEN
DBMS_OUTPUT.put_line ('冬天');
ELSE
DBMS_OUTPUT.put_line ('月份不合法');
END IF;
END;
/
4. case
SET SERVEROUTPUT ON DECLARE
score VARCHAR (20) := '良';
BEGIN
CASE score
WHEN '优'
THEN
DBMS_OUTPUT.put_line ('学霸你好');
WHEN '良'
THEN
DBMS_OUTPUT.put_line ('命中注定你是个普通人');
WHEN '差'
THEN
DBMS_OUTPUT.put_line ('未来的老板');
ELSE
DBMS_OUTPUT.put_line ('不要乱赋值');
END CASE;
END;
/
循环语句(3种)
1.loop
先执行一次循环体,然后再判断 exit when 关键字后面的条件表达式的值是ture还是false,如果是true退出循环,如果是flase则继续执行
SET SERVEROUTPUT ON DECLARE
num INT := 5;
BEGIN
LOOP
DBMS_OUTPUT.put_line ('num=' || num);
num := num - 1;
EXIT WHEN num = 2;
END LOOP; DBMS_OUTPUT.put_line ('执行完成');
END;
/
2.while
先判断表达式,在循环。有可能执行0次
SET SERVEROUTPUT ON DECLARE
num INT := 5;
BEGIN
WHILE num >= 1
LOOP
DBMS_OUTPUT.put_line ('num=' || num);
num := num - 1;
END LOOP; DBMS_OUTPUT.put_line ('执行完成');
END;
/
3.for
语法:
for a in [reverse] b..c
loop
...
end loop;
a: 整数变量,用来作为计数器,默认计数器循环递增,如果加上了[reverse] 表示循环递减
b:计数器下限值,当计数器的值小于下限值时,程序循环终止
c:计数器上限值,当计数器的值大于上限值时,程序循环终止
SET SERVEROUTPUT ON DECLARE
num INT := 6;
BEGIN
FOR i IN 3 .. 5 --i初始值是3,共执行三遍
LOOP
DBMS_OUTPUT.put_line ('num=' || num);
END LOOP; DBMS_OUTPUT.put_line ('执行完成');
END;
/
六、PL/SQL游标
在PL/SQL里使用游标代表集合
1.显示游标
声明游标
声明游标要在pl\sql的declare里
cursor 游标名[(变量名 in 类型:='')]
[return 返回值类型]
is sql语句
DECLARE
CURSOR cur_n IS
SELECT id,name FROM student WHERE name= 'tom';
DECLARE
CURSOR cur_n(name1 in varchar2:='tom') IS--不要指定varchar2的长度,否则报错
SELECT id,name FROM student WHERE name = name1;
打开游标
在打开游标的过程中,程序首先将符合条件的记录送人内存中,然后再将指‘针指’向第一条记录
打开游标要写在begin里
格式:
open 游标名[参数]
open cur_n;
open cur_n('tom');
读取游标
打开游标后,开始读取游标中的数据,读取方式是逐行将结果数据保存到变量中
格式:
fetch 游标名 into 变量
fetch cur_n into
2.游标属性
无论是显示游标还是隐式游标,都具有 %found %notfound %isopen %rowcount 四个属性
通过这四个属性可以获知sql语句的执行结果以及该游标的状态信息。
%found: 布尔型属性,如果SQL语句至少影响到一行数据,则改属性为true,否则为false
%notfound:与%found功能相反
%rowcount:数字型属性,返回受sql语句影响的行数
%isopen:布尔型属性,当游标已经打开时返回true,关闭时则false
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;
/
3.隐示游标
4.带参数光标
带参数的游标就定义的时候和open的时候与不带参数的游标有区别
declare
--定义一个参数
cursor cemp(dno number) is select ename from emp where deptno=dno;
pename emp.ename%type;
begin
open cemp(10);--传参
loop
fetch cemp into pename;
exit when cemp%notfound;
dbms_output.put_line(pename);
end loop;
close cemp;
end;
/
5.光标数的限制
oracle数据库只允许在同一个会话中打开300个光标。
修改光标数的限制:
alter system set open_cursors=400 scope=both;--允许400光标
scope取值有三种:memory(只更改当前实例),spfile(只更改参数文件--数据库需要重启),both(前两者同时更改)
七、异常
异常格式:
exception
when 异常类型 then
...
when 异常类型 then
...
end;
预定义异常
zero_divide:除数为零时引发的异常
access_into_null:企图为某个未初始化对象的属性赋值
collection_is_null:企图使用未初始化的集合元素
cursor_already_open:企图再次打开一个已经打开过的游标,但重新打开之前,游标未关闭
invalid_number:企图将一个字符串转换成一个无效的数字而失效
login_denied:企图使用无效的用户名或密码连接数据库
no_data_found:select into 语句没有返回数据
rowtype_mismatch:主游标变量与PL/SQL游标变量的返回类型不兼容
self_is_null:使用对象类型时,使用空对象调用其方法
subscript_beyond_count:元素下标超过嵌套表或varray的最大值
subscript_outside_limit: 企图使用非法索引号引用嵌套表或varray中的元素
sys_invalid_rowid:字符串向rowid转换时的错误,因为该字符串不是一个有效的rowid值
timeout_on_resource oracle在等待资源时超时
too_many_rows 执行select into 语句时,结果集超过一行引发的异常
例:
no_data_found
declare
pename emp.ename%type;
begin
select ename into pename from emp where empno=1234;
exception
when no_data_found then dbms_output.put_line('未找到该员工');
--除了上面的异常以外的所有异常
when others then dbms_output.put_line('其他例外');
end;
/
too_many_rows
declare
pename emp.ename%type;
begin
--如果返回多行数据会报异常
select ename into pename from emp where deptno=10;
exception
when too_many_rows then dbms_output.put_line('打印了多行');
--除了上面的异常以外的所有异常
when others then dbms_output.put_line('其他例外');
end;
/
自定义异常
declare
cursor cemp is select ename from emp where deptno=99;
pename emp.ename%type;
--自定义异常
no_emp_found exception;
begin
open cemp;
fetch cemp into pename;
if cemp%notfound then
--抛出异常
raise no_emp_found;
-- 当发生异常后,oracle调用close自动关闭
close cemp;
exception
whenno_emp_found then dbms_output.put_line('没有找到员工');
when others then dbms_output.put_line('其他例外');
end;
/
(18)PL/SQL的更多相关文章
- PL/SQL异常处理方法
PL/SQL异常处理方法 1:什么是异常处理: PL/SQL提供一个功能去处理异常,在PL/SQL块中叫做异常处理,使用异常处理我们能够测试代码和避免异常退出. PL/SQL异常信息包含三个部分: ...
- Oracle 学习笔记 18 -- 存储函数和存储过程(PL/SQL子程序)
PL/SQL子程序 它包含了函数和过程.此功能是指用户定义的函数.和系统功能是不同的.子程序通常完成特定的功能PL/SQL座.,能够被不同的应用程序多次调用.Oracle提供能够把PL/SQL程序存储 ...
- 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》
本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...
- ORA-06502:PL/SQL :numberic or value error: character string buffer too small
今天遇到一个错误提示:ORA-06502:PL/SQL :numberic or value error: character string buffer too small,一般对应的中文信息为:O ...
- 【Java EE 学习 29 上】【PL/SQL】【存储过程】【存储函数】【触发器】
一.PL/SQL简介 1.概念:PL/SQL语言是Oracle数据库专用的一种高级程序设计语言,是对标准SQL语言进行了过程化扩展的语言. 2.功能:既能够实现对数据库的操作,也能够通过过程化语言中的 ...
- PL/SQL Block Structure
[顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日之功) 继上四篇:ORACLE PL/SQL编程之八:把触发器说透 ORAC ...
- ORACLE PL/SQL编程详解
ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...
- PL/SQL基础2(笔记)
1 第一个PL/SQL的程序 DECLARE BEGIN DBMS_OUTPUT.PUT_LINE('Hello World!'); END; / --2一个简单的PL/SQL程序 DECLARE v ...
- PL/SQL之--触发器
一.简介 触发器在数据库里以独立的对象进行存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来触发运行.oracle事件指的是对数据库的表或视图进行的inse ...
随机推荐
- shell脚本简单切割字符串
我们有这样一个字符串: info='abcd;efgh' 现在想获取abcd和efgh,我们可以简单地用cut工具来获取: fstr=`` sstr=`` 这里主要是用了cut工具的-d和-f参数: ...
- Oracle 学习----:Oracle删除表时报错:表或视图不存在
表明明存在,但是删除时却报错:表或视图不存在. 可能的原因之一是表名包含了小写,可以用双引号包含表名通过drop命令来删除, 如下所示: drop table "tmp_ST" ; ...
- sqlalchemy 查询姿势总结
sqlalchemy查询使用 1.带条件查询 查询是最常用的,对于各种查询我们必须要十分清楚,首先是带条件的查询 #带条件查询 rows = session.query(User).filter_by ...
- 孤荷凌寒自学python第十五天python循环控制语句
孤荷凌寒自学python第十五天python循环控制语句 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) python中只有两种循环控制语句 一.while循环 while 条件判断式 1: ...
- Struts2+DAO层实现实例03——添加监听器跟踪用户行为
实例说明 根据上两次的成品进行二次加工. 加入Listener,监听用户的登陆注销情况. 所用知识说明 采用SessionBindingListener对Session进行监听. 同时,Action中 ...
- SVN基本介绍
SVN是一种项目合作开发的软件,参与项目的人员可以在不同的地方实现文件和目录的超时空共享. 两个重要的概念: 1.配置库(Repository) SVN的核心是配置库,储存所有的数据,配置库按照文件树 ...
- 一些需要注意的ts
写了一段时间ts,在从头学习一遍,温故而之新 ts的一些技巧 1.巧用注释 通过/** */形式的注释可以给 TS 类型做标记,编辑器会有更好的提示: /** A cool guy. */ inter ...
- CPU封装技术介绍
所谓“CPU封装技术”是一种将集成电路用绝缘的塑料或陶瓷材料打包的技术.以CPU为例,我们实际看到的体积和外观并不是真正的CPU内核的大小和面貌,而是CPU内核等元件经过封装后的产品. CPU封装对于 ...
- zoj 1508 Intervals (差分约束)
Intervals Time Limit: 10 Seconds Memory Limit: 32768 KB You are given n closed, integer interva ...
- 内存检测工具valgrind
valgrind --tool=memcheck --leak-check=full --error-limit=no --trace-children=yes ./server valgrind ...