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的更多相关文章

  1. PL/SQL异常处理方法

    PL/SQL异常处理方法   1:什么是异常处理: PL/SQL提供一个功能去处理异常,在PL/SQL块中叫做异常处理,使用异常处理我们能够测试代码和避免异常退出. PL/SQL异常信息包含三个部分: ...

  2. Oracle 学习笔记 18 -- 存储函数和存储过程(PL/SQL子程序)

    PL/SQL子程序 它包含了函数和过程.此功能是指用户定义的函数.和系统功能是不同的.子程序通常完成特定的功能PL/SQL座.,能够被不同的应用程序多次调用.Oracle提供能够把PL/SQL程序存储 ...

  3. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

  4. 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 ...

  5. 【Java EE 学习 29 上】【PL/SQL】【存储过程】【存储函数】【触发器】

    一.PL/SQL简介 1.概念:PL/SQL语言是Oracle数据库专用的一种高级程序设计语言,是对标准SQL语言进行了过程化扩展的语言. 2.功能:既能够实现对数据库的操作,也能够通过过程化语言中的 ...

  6. PL/SQL Block Structure

    [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日之功) 继上四篇:ORACLE PL/SQL编程之八:把触发器说透                ORAC ...

  7. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  8. PL/SQL基础2(笔记)

    1 第一个PL/SQL的程序 DECLARE BEGIN DBMS_OUTPUT.PUT_LINE('Hello World!'); END; / --2一个简单的PL/SQL程序 DECLARE v ...

  9. PL/SQL之--触发器

    一.简介 触发器在数据库里以独立的对象进行存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来触发运行.oracle事件指的是对数据库的表或视图进行的inse ...

随机推荐

  1. shell脚本简单切割字符串

    我们有这样一个字符串: info='abcd;efgh' 现在想获取abcd和efgh,我们可以简单地用cut工具来获取: fstr=`` sstr=`` 这里主要是用了cut工具的-d和-f参数: ...

  2. Oracle 学习----:Oracle删除表时报错:表或视图不存在

    表明明存在,但是删除时却报错:表或视图不存在. 可能的原因之一是表名包含了小写,可以用双引号包含表名通过drop命令来删除, 如下所示: drop table "tmp_ST" ; ...

  3. sqlalchemy 查询姿势总结

    sqlalchemy查询使用 1.带条件查询 查询是最常用的,对于各种查询我们必须要十分清楚,首先是带条件的查询 #带条件查询 rows = session.query(User).filter_by ...

  4. 孤荷凌寒自学python第十五天python循环控制语句

    孤荷凌寒自学python第十五天python循环控制语句 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) python中只有两种循环控制语句 一.while循环 while 条件判断式 1: ...

  5. Struts2+DAO层实现实例03——添加监听器跟踪用户行为

    实例说明 根据上两次的成品进行二次加工. 加入Listener,监听用户的登陆注销情况. 所用知识说明 采用SessionBindingListener对Session进行监听. 同时,Action中 ...

  6. SVN基本介绍

    SVN是一种项目合作开发的软件,参与项目的人员可以在不同的地方实现文件和目录的超时空共享. 两个重要的概念: 1.配置库(Repository) SVN的核心是配置库,储存所有的数据,配置库按照文件树 ...

  7. 一些需要注意的ts

    写了一段时间ts,在从头学习一遍,温故而之新 ts的一些技巧 1.巧用注释 通过/** */形式的注释可以给 TS 类型做标记,编辑器会有更好的提示: /** A cool guy. */ inter ...

  8. CPU封装技术介绍

    所谓“CPU封装技术”是一种将集成电路用绝缘的塑料或陶瓷材料打包的技术.以CPU为例,我们实际看到的体积和外观并不是真正的CPU内核的大小和面貌,而是CPU内核等元件经过封装后的产品. CPU封装对于 ...

  9. zoj 1508 Intervals (差分约束)

    Intervals Time Limit: 10 Seconds      Memory Limit: 32768 KB You are given n closed, integer interva ...

  10. 内存检测工具valgrind

    valgrind --tool=memcheck --leak-check=full --error-limit=no  --trace-children=yes  ./server valgrind ...