一、Oracle数据库
1.1、基本介绍
Oracle数据库的一个基本任务是存储数据。Oracle数据库服务器是由一个数据库和至少一个数据库实例组成。数据库是一组存储的文件,而数据库实例是一组管理数据文件的内存结构。另外,数据库由后台进程组成。
一个数据库和一个实例是紧密相连的,因此术语- Oracle数据库通常用来指代实例和数据库。
1.2、存储结构
-
物理结构是存储数据的纯文件。当执行
CREATE DATABASE
语句来创建一个新的数据库时,将 创建- 数据文件:数据文件包含真实数据。逻辑数据库结构(如表和索引)的数据被物理存储在数据文件中。
- 控制文件:每个Oracle数据库都有包含元数据的控制文件。元数据描述数据库的物理结构,包括数据库名称和数据库文件位置
- 联机重做日志文件:每个Oracle数据库都有一个联机重做日志,其中包含两个或多个联机重做日志文件。联机重做日志由重做条目组成,记录数据所做的所有更改
- 参数文件
- 物理文件
- 备份文件
- 归档重做日志文件
-
逻辑存储结构对磁盘空间使用情况进行精细控制。
-
数据块:数据块对应于磁盘上的字节数。Oracle将数据存储在数据库中。数据块也被称之为逻辑块,Oracle块或页。
-
范围:范围是用于存储特定类型信息的逻辑连续数据块的具体数量。
-
段:段是分配于存储用户对象(例如表或索引)的一组范围
-
表空间:数据库被分成称为表空间的逻辑存储单元。表空间的段逻辑容器。每个表空间至少包含一个数据文件。
-
1.3、Oracle实例
Oracle实例是客户端应用程序(用户)和数据库之间的接口。Oracle实例是由三个主要部分组成:系统全局区(SGA),程序全局区(PGA)和后台进程如下图所示
SGA是实例启动时分配的共享内存结构,关闭时释放。SGA是一组包含一个数据库实例的数据库和控制信息的共享内存结构。不同于所有进程斗可用的SGA,PGA是会话开始时为每个回话分配的私有内存区,当会话结束时释放。
- PMON是调节所有其他进程的进程监视器。PMON清理异常连接的数据库连接,并自动向侦听器进程注册数据库实例。PMON是Oracle数据库中最活跃的一个进程。
- SMON是执行系统及清理操作的系统监视进程。它有两个主要职责,包括在发生故障的情况下自动回复实例,例如断电和清理临时文件。
- DBWn是数据库编写器。Oracle在内存中执行每个操作而不是磁盘。因为在内存中的处理速度比在磁盘上快。DBWn进程从磁盘读取数据并将其写回到磁盘。一个Oracle实例有许多数据库编写器,如DBW0,DBW1,DBW2等等
- CKPT是检查点过程。在Oracle中,磁盘上的数据库称为块,内存中的数据称为缓冲区。当该块写入缓冲区并更改时,缓冲区变脏,需要将其写入磁盘。CKPT进程使用检查点信息更新控制和数据文件头,并向脏盘写入脏缓冲区的信号。请注意,Oracle12C允许全面和增量检查点。
- LGWR是日志写入过程,是可恢复架构的关键。在数据库中发生的每一个变化都写出到一个名为redo日志文件中用于恢复目的。而这些变化是由LGWR进程编写的。LGWR进程首先将更改写入内存,然后将磁盘写入重做日志,然后将其用于恢复。
- ARCn是归档进程,它将重做日志的内容复制到归档重做日志文件。存档程序进程可用有多个进程,如:ARC0,ARC1和ARC3,允许存档程序写入多个目标。
- MMON是收集性能指标的可管理性监控流程。
- MMAN是自动管理Oracle数据库内存的内存管理器。
- LREG是监听器注册过程,它使用ORacle Net Listener 在数据库实例和调度程序进程上注册信息。
二、配置Oracle【Docker】
2.1、安装Oracle
1、下载Docker
apt install docker.io
2、下载Oracle镜像
docker pull oracleinanutshell/oracle-xe-11g
3、运行Docker容器
docker run -d -v /home/docker/data/oracle_data:/data/oracle_data -p 49160:22 -p 1521:1521 -e ORACLE_ALLOW_REMOTE=true oracleinanutshell/oracle-xe-11g
# -d 持久化运行
# -v 映射目录
# -p 绑定端口
# -e ORACLE_ALLOW_REMOTE=true 配置远程登录
此时连接参数为:
hostname: localhost
port: 1521
sid: xe
username: system
password: oracle
4、修改system默认密码
#1.进入容器
docker exec -it oracleinanutshell/oracle-xe-11g bash
#2.连接sqlplus
su oracle
sqlplus "/as sysdba"
#3.修改密码
alter User system identified by 新密码
2.2、配置用户
查看默认表空间
select FILE_NAME from dba_temp_files
-
进入容器,连接到oracle服务
#1.进入容器 docker exec -it oracleinanutshell/oracle-xe-11g bash #2.连接sqlplus su oracle sqlplus "/as sysdba"
-
创建表空间
#bash: cd /data/oracle_data mkdir test chmod 777 test #sqlplus: create tablespace TEST datafile '/data/oracle_data/test/test.dbf' size 100M; /* datafile 用于设置物理文件名称 size 用于设置表空间的初始大小 autoextend on 用于设置自动增长,如果存储量超过初始大小,则开始自动扩容 next 用于设置扩容的空间大小 */
-
创建用户(DCL)
create user XIANG identified by x1270059552 default tablespace TEST; # 如果新建用户失败,可能是这个用户已经存在,要先删除 # drop user TEST cascade; #如果不配置表空间的话,使用默认表空间
-
用户授权(DCL)
grant connect,resource to XIANG; grant create session to XIANG; //创建会话权限; grant dba to XIANG;//授予dba权限后,这个用户能操作所有用户的表 //Connect 角色,是授予最终用户的典型权利,最基本的权利,能够连接到ORACLE数据库中,并在对其他用户的表有访问权限时,做SELECT、UPDATE、INSERTT等操作。 //Resource 角色,是授予开发人员的,能在自己的方案中创建表、序列、视图等。 //DBA角色,是授予系统管理员的,拥有该角色的用户就能成为系统管理员了,它拥有所有的系统权限。
三、Oracle基础
3.1、字符类型
字符型 | 大小 |
---|---|
CHAR | 固定字符类型,最大2000B |
VARCHAR2 | 可变字符类型,最大4000B |
LONG | 大文本类型,最大2G |
数值型 | |
NUMBER | |
MUMBER(n) | n位数 |
MUNBER(n,m) | 一共n位数,小数点后m为 |
日期类型 | |
DATE | 精确到秒 |
TIMESTAMP | 精确到小数点后9为 |
二进制型 | |
CLOB | 存储字符,最大4G |
BLOB | 存储图像,声音,视频,二进制数,最大4G |
3.2、DDL基础知识
-
新建表格
CREATE TABLE t_owenrs ( id NUMBER primary key, name VARCHAR2(30), addressid NUMBER, housenumber VARCHAR2(30), watermeter VARCHAR2(30), adddate DATE, ownertyoeid NUMBER )
-
增加字段
ALTER TABLE t_owenrs MODIFY ( REMARK CHAR(2), OUTDATA TIMESTAMP )
-
修改字段
ALTER TABLE t_owenrs RENAME COLUMN 原列名 TO 新列名
-
删除字段
--删除一个字段 ALTER TABLE 表名称 DROP COLUMN 列名 --删除多个字段 ALTER TABLE 表名称 DROP (列名 1,列名 2...)
-
删除表
DROP TABLE 表名称
3.3、DML基础知识
-
插入数据
insert into 表名称 to values(value,value,value,value,value); //commit;有事务记得提交 //INSERT INTO "T_OWENRS" VALUES ('1', '1', '1', '1', '1', TO_DATE('2023-12-13 16:08:01', 'SYYYY-MM-DD HH24:MI:SS'), '1'); //INSERT INTO "T_OWENRS" ("ID", "NAME", "ADDRESSID", "HOUSENUMBER", "WATERMETER", "ADDDATE", "OWNERTYOEID") VALUES ('1', '1', '1', '1', '1', TO_DATE('2023-12-13 16:08:01', 'SYYYY-MM-DD HH24:MI:SS'), '1');
-
修改数据
update 表名称 set 列1=修改值,列2=修改值 where 条件 //commit;有事务记得提交 //UPDATE "T_OWENRS" SET NAME=666,HOUSENUMBER=888 WHERE ID=1;
-
删除数据
-
语法一:
delete from tableName where 条件; //commit;有事务记得提交
-
语法二:
truncate table tableName; //commit;有事务记得提交
-
区别:
- delete 删除的数据可以 rollback
- delete 删除可能产生碎片,并且不释放空间
- truncate 是先摧毁表结构,再重构表结构
-
四、Oracle查询
4.1、单表查询
1、简单查询
-
精确查询
select * from T_OWNERS where ID='4'
-
模糊查询
select * from T_OWNERS where NAME like '%张%'
-
and运算符
select * from T_OWNERS where NAME='张三' and ID='1'
-
or运算符
select * from T_OWNERS where NAME='张三' or ADDRESS='4300000'
-
and与or运算符混合使用
select * from T_OWNERS where (NAME='张三' or ADDRESS='4300000') and ID='1'
-
范围查询
select * from T_OWNERS where ID>'0' and ID<'100'
-
空置查询
select * from T_OWNERS where ADDRESS is null
-
精确日期查询
SELECT * FROM T_OWNERS WHERE ADDDATE=TO_DATE('2015-04-12 00:00:00','yyyy-MM-dd HH24:mi:ss')
-
日期范围查询
SELECT * FROM T_OWNERS WHERE ADDDATE BETWEEN TO_DATE('2015-04-12 00:00:00','yyyy-MM-dd HH24:mi:ss') AND TO_DATE('2016-09-11 00:00:00','yyyy-MM-dd HH24:mi:ss')
-
同义词
create synonym OWNERS for T_OWNERS;//私有同义词
create public synonym OWNERS for T_OWNERS;//共有同义词
select * from OWNERS;//使用同义词查询
2、去重查询
select distinct address from T_OWNERS
3、排序查询
-
升序查询
select * from T_ACCOUNT order by usenum
-
降序查询
select * from T_ACCOUNT order by usenum desc
4、基于伪列查询
-
ROWID(表中的每一行在数据文件中都有一个物理地址)
SELECT ROWID ,"T_OWENRS".* FROM "T_OWENRS"
-
ROWNUM(展示当前行)
SELECT ROWNUM ,"T_OWENRS".* FROM "T_OWENRS"
5、聚合查询
-
聚合函数
-
求和
SELECT SUM(NAME) FROM "T_OWENRS" WHERE OWNERTYOEID = '1'
-
平均数
SELECT AVG(NAME) FROM "T_OWENRS" WHERE OWNERTYOEID = '1'
-
最大值
SELECT MAX(NAME) FROM "T_OWENRS" WHERE OWNERTYOEID = '1'
-
最小值
SELECT MIN(NAME) FROM "T_OWENRS" WHERE OWNERTYOEID = '1'
-
计数
SELECT COUNT(NAME) FROM "T_OWENRS" WHERE OWNERTYOEID = '1'
-
-
分组聚合Group
SELECT COUNT(NAME), HOUSENUMBER FROM "T_OWENRS" GROUP BY HOUSENUMBER
-
分组后条件查询having
/*分组后查询'HOUSENUMBER'大于'2'的数据*/ SELECT COUNT(NAME) , HOUSENUMBER FROM "T_OWENRS" GROUP BY HOUSENUMBER HAVING HOUSENUMBER > '2'
4.2、连接查询
1、内连接[交集]
SQL1999语法
SELECT a.A_ID ID,a.A_NAME NAME,a.A_PART PART
FROM A_TABLE a INNER JOIN B_TABLE b
on a.A_ID = b.B_ID
oracle语法
[可以省略INNER JOIN 使用where代替on]
SELECT a.A_ID ID,a.A_NAME NAME,a.A_PART PART
FROM A_TABLE a, B_TABLE b
WHERE a.A_ID = b.B_ID
2、左外连接[左并集]
SQL1999语法
SELECT a.A_ID ID,a.A_NAME NAME,a.A_PART PART
FROM A_TABLE a LEFT JOIN B_TABLE b
ON a.A_ID = b.B_ID
ORDER BY a.A_ID
oracle语法
[右边用+
号]
SELECT a.A_ID ID,a.A_NAME NAME,a.A_PART PART
FROM A_TABLE a , B_TABLE b
WHERE a.A_ID = b.B_ID(+)
ORDER BY a.A_ID
3、右外连接[右并集]
SQL1999语法
SELECT b.B_ID ID,b.B_NAME NAME,b.B_PART PART
FROM A_TABLE a RIGHT JOIN B_TABLE b
ON a.A_ID = b.B_ID
ORDER BY b.B_ID
oracle语法
[左边用+
号]
SELECT b.B_ID ID,b.B_NAME NAME,b.B_PART PART
FROM A_TABLE a , B_TABLE b
WHERE a.A_ID(+) = b.B_ID
ORDER BY b.B_ID
4、全连接[并集]
SELECT *
FROM A_TABLE a FULL JOIN B_TABLE b
on a.A_ID = b.B_ID
4.3、子查询
1、where子查询
-
单行子查询
SELECT * FROM T_ACCOUNT WHERE YEAR ='2012' AND MONTH = '01' AND USENUM > ( /*子查询中返回一条数据*/ SELECT AVG(USENUM) FROM T_ACCOUNT WHERE YEAR ='2012' AND MONTH = '01' )
-
多行子查询
SELECT * FROM T_OWNERS WHERE ADDRESSID in ( SELECT ID FROM T_ADDRESS WHERE NAME LIKE '%花园%' )
2、from子查询
SELECT *
FROM
(
SELECT *
FROM T_ADDRESS
WHERE NAME LIKE '%花园%'
)
WHERE AREAID = '1'
3、select子查询
select id,name,
(select name from t_address where id=addressid) addressname
from t_owners
4.4、分页查询
1、简单分页
/*ROWNUM五条记录*/
SELECT *
FROM T_OWNERS
WHERE ROWNUM <= 5
/*ROWNUM第六条到第十条记录使用FROM子查询查询*/
SELECT *
FROM (
SELECT ROWNUM num,T_OWNERS.*
FROM T_OWNERS
WHERE ROWNUM <= 10
)
WHERE num > 5
2、基于排序的分页
/*使用三层嵌套子查询*/
SELECT *
FROM
(
SELECT ROWNUM nums,t.*
FROM
(
SELECT ROWNUM num,T_OWNERS.*
FROM T_OWNERS
WHERE ROWNUM <= 10
ORDER BY WATERMETER DESC
) t
ORDER BY t.WATERMETER
)
WHERE nums > 5
4.5、单行函数
(一)、字符函数
1.求字符串长度 LENGTH
Select length('ABCD') From tableName
2.截取字符串 SUBSTR
Select Substr('ABCD',2,2) From tableName
3.字符串拼接 CONCAT
Select Concat('ABC','D') From tableName
(二)、数值函数
1.四舍五入函数 ROUND
Select round(A1) From tableName
Select round(A1,2[小数点后位数]) From tableName
2.截取函数 TRUNC
Select trunc(A1) From tableName
Select trunc(A1,2[小数点后位数]) From tableName
3.取模函数 MOD
Select mod(A1,N) From tableName
(三)、日期函数
1.获取系统日期时间 sysdate
Select sysdate From tableName
2.加月函数ADD_MONTHS
Select add_months(sysdate,N) From tableName
3.求所在月最后一天LAST_DAY
Select last_day(sysdate) From tableName
4.日期截取函数
Select trunc(sysdate,'yyyy') From tableName
Select trunc(sysdate,'mm') From tableName
(四)、转换函数
1.数字转字符串TO_CHAR
Select to_char(1024) from tableName
2.日期转字符串
Select to_char(sysdate,'yyyy-mm-dd') from tableName
select to_char(sysdate,'yyyy-MM-dd HH:mm:ss') from tableName;
3.字符串转日期TO_DATE
Select to_date('2027-01-01','yyyy-mm-dd') from tableName
4.字符串转数字TO_NUMBER
Select to_number('100') From tableName
(五)、其他函数
1.空值处理函数NVL
如果检测A列为null,用N替换
Select NVL(A,N) From tableName
2.空值处理函数NVL2
如果检测A列为null,用N替换,否则为M
Select NVL2(A,M,N)
3.条件取值decode
Select T_ADDRESS.NAME,decode(T_ADDRESS.AREAID,
1,'别墅',
2,'小区',
3,'花园'
) as 小区等级 From T_ADDRESS
(六)、行列转换
略
(七)、分析函数
1.排名-重复累加
Select rank() over(ORDER BY T_ADDRESS.AREAID DESC),T_ADDRESS.AREAID FROM T_ADDRESS
2.排名-重复不累加
Select dense_rank() over(ORDER BY T_ADDRESS.AREAID DESC),T_ADDRESS.AREAID FROM T_ADDRESS
3.排名-连续排名
Select row_number() over(ORDER BY T_ADDRESS.AREAID DESC),T_ADDRESS.AREAID FROM T_ADDRESS
4.row_number()实现分页不用三层子查询
select *
from
(select row_number() over(order by usenum desc )
rownumber,usenum from T_ACCOUNT)
where rownumber>10 and rownumber<=20
(八)、集合运算
1、并集运算UNION ALL(UNION)
2、交集运算INTERSECT
3、差集运算MINUS
五、视图
5.1、普通视图
-
创建视图
create [or replace] [force] view view_name as 查询语法 [with check option] [with read only] /* or replace:若创建的视图已存在,则自动重建 force:不管基表是否存在 oracle 自动重建该视图 with check option:修改或插入数据行必须满足视图定义的的约束 with read only:改视图上不能进行任何DML操作 */
-
删除视图
DROP view view_name
-
案例
create or replace view view_name as select * from table_Name where condition --查询-- select * from view_name
-
带检约束的视图
create or replace view view_name as select * from table_name where id =2 with check option --执行更新-- update view_name set id =3 where name = 'zhangsan' --执行报错-- 视图的约束是id = 2 不能修改
-
只读视图
create or replace view view_name as select * from table_name where id =2 with read only
-
注意
- 键保留表【该表的主键列全部显示在图中,并且它们的值在视图中都是唯一且非空的】的字段是可以更新的,非键保留表的字段不能更新
5.2、物化视图
查看普通视图相当于一个虚拟表,每次查看都是访问一条特定查询集的查询结果,而物化视图
建立的是副本,需要占用存储空间。查询物化视图的执行效率相当于查询一个表。
-
创建物化视图语法
create materialized view view_name [build immediate | build deferred] //是否创建时生成数据 默认是生成 refresh [fast | complete | force] //刷新模式 修改局部刷新,修改全局刷新,判断刷新[默认] [ on [commit | demand] | start with (start_time) next (next_time) //自动刷新或手动刷新[默认] ] as subquery
-
案例
create materialized view mv_address as select ad.id,ad.name adname,ar.name ar_name from t_address ad,t_area ar where ad.areaid=ar.id
向地址表中插入一条新数据
insert into t_address values(8,'宏福苑小区',1,1);
物化视图并没有更新,通过PL/SQL手动刷新
begin DBMS_MVIEW.refresh('MV_ADDRESS','C'); end;
-
创建增量刷新的物化视图
如果创建增量刷新的物化视图,必须首先创建物化视图日志
create materialized view log on t_address with rowid; create materialized view log on t_area with rowid
创建的日志名称为MLOG$_表名称
创建物化视图
create materialized view view_name refresh fast as select ad.rowid adrowid ,ar.rowid arrowid, ad.id,ad.name adname,ar.name ar_name from t_address ad,t_area ar where ad.areaid=ar.id;
注意:
-
创建物化视图中涉及表的物化视图日志。
-
在查重中,必须包含所有表的rowid(已rowid方式建立物化视图日志)
-
手动刷新物化视图后,日志会被清空
begin DBMS_MVIEW.refrech('view_name','C') end;
-
六、序列
由于oracle没有向mysql一样的AUTO_INCREMENT属性来实现主键自增长所以我们需要通过创建序列来实现此功能
-
创建序列
create sequence sequence_name [increment by n] //递增序列值是N,默认1 [start with n] //开始值 [maxvalue n] //最大值 [minvalue n] //最小值 [{cycle | nocycle}]//是否循环,默认不循环 [{cache n | nocache}]//是否分配并存入内存中
-
查询序列
--查询序列下一个值-- select sequence_name.nextval from dual --查询序列当前的值-- select sequence_name.currval from dual --查询所有序列-- select * from user_sequences
-
修改删除序列
--修改序列-- alter sequence sequence_name maxvalue cycle 5000 --删除序列-- drop sequence sequence_namee
七、索引
使用索引可大大降低IO读取时间,提高数据访问性能。类似于书本中的目录一样。它的形式类似于一棵树一样,而树的节点存储的就是每条记录的物理位置。就是之前提到的伪列 ROWID
7.1、普通索引
create index index_name on table(column)
7.2、唯一索引
create unique index index_name on table(column)
7.3、复合索引
create index index_name on table(column1,column2)
7.4、反向键索引
用于索引列是自动增长的情况
create index index_name on table(column) reverse
7.5、位图索引
create bitmap index index_name on table(column)
八、PL/SQL
PL/SQL(Procedure Language/SQL)是 Oracle 对 sql 语言的过程化扩展,指在 SQL 命令语言中增加了过程处理语句(如分支、循环等),使 SQL 语言具有过程处理能力。把 SQL 语言的数据操纵能力与过程语言的数据处理能力结合起来,使得 PLSQL 面向过程但比过程语言简单、高效、灵活和实用。
Wdeclare
--声明变量--
begin
--代码逻辑--
[exception
--异常处理--
]
end;
8.1、变量
声明变量:变量名 类型(长度)
变量赋值:变量:=变量值
例如:
声明变量水费单价、水费字数、吨数、金额。对水费单价、字数、进行赋值 。吨数根据水费字数换算,规则为水费字数除以1000,并且四舍五入,保留两位小数。计算金额,金额=单价*吨数。输出单价 、数量和金额。
declare
v_price number(10,2);
v_usenum number;
v_usenum2 number(10,2);
v_money number(10,2);
begin
v_price:=2.45;
v_usenum:=8012;
--字符换成吨数--
v_usenum2:=round(v_usenum/1000,2);
--计算金额--
v_money:=round(v_usenum2*v_price,2);
dbms_output.put_line('单价:'||v_price||'吨数:'||v_usenum2||'金额:'||v_money);
end;
8.2、Select into 方式 赋值
语法结构
select * 列明 into 变量名 from 表名 where 条件
--注意:结果必须是一条数据,多条数据和没有数据会报错--
例如:
declare
v_price number(10,2);--单价
v_usenum number;--水费字数
v_num0 number;--上月字数
v_num1 number;--本月字数
v_usenum2 number(10,2);--使用吨数
v_money number(10,2);--水费金额
begin
--对单价进行赋值--
v_price:=3.45;
--变量赋值--
select usenum,num0,num1 into v_usenum,V_num0,V_num1
from T_ACCOUNT
where year='2012' and month='01' and owneruuid=1;
--计算--
v_usenum2:= round(v_usenum/1000,2);
v_money:=v_price*v_usenum2;
--输出--
DBMS_OUTPUT.put_line('单价:'||v_price||'吨数:' ||v_usenum2||'金额:'||v_money||'上月字数:'||v_num0||'本月字数'||v_num1);
end;
8.3、属性类型
-
%TYPE 引用型
定义一个变量,其数据类型与已经定义的某个 数据变量的类型相同,或者与数据库表的某个列的数据类型
相同,这时可以使用%TYPE。优点在于:-
所引用的数据库列的数据类型可以不必知道;
2. 所引用的数据库列的数据类型可以实时改变;
-
-
%ROWTYPE:
PL/SQL 提供%ROWTYPE 操作符, 返回一个记录类型, 其数据类型和数据库表的数据结构相一致。优点在于:- 所引用的数据库中列的个数和数据类型可以不必知道;
- 所引用的数据库中列的个数和数据类型可以实时改变;
--变量的用法-- declare v_price number(10,2);--单价 v_account T_ACCOUNT%ROWTYPE;--记录型 v_usenum2 number(10,2);--使用吨数 v_money number(10,2);--水费金额 begin --对单价进行赋值 v_price:=3.45; --赋值 select * into v_account from T_ACCOUNT where year='2012' and month='01' and owneruuid=1; --使用吨数 v_usenum2:= round(v_account.usenum/1000,2); --计算金额 v_money:=v_price*v_usenum2; DBMS_OUTPUT.put_line('单价:'||v_price||'吨数:' ||v_usenum2||'金额:'||v_money||'上月字数:'||v_account.num0||'本月字'||v_account.num1); end;
8.4、异常
发生异常后,语句讲停止执行,控制权转移到PL/SQL块的异常处理部分异常有两种类型:
1. 预定异常
2. 用户定义异常
Oracle预定异常21个,常用的7个
异常名称 | 异常码 | 描述 |
---|---|---|
DUP_VAL_ON_INDEX | ORA-00001 | 试图向唯一索引列插入重复值 |
INVALID_CURSOR | ORA-01001 | 试图进行非法游标操作。 |
INVALID_NUMBER | ORA-01722 | 试图将字符串转换为数字 |
NO_DATA_FOUND | ORA-01403 | SELECT INTO 语句中没有返回任何记录。 |
TOO_MANY_ROWS | ORA-01422 | SELECT INTO 语句中返回多于 1 条记录。 |
ZERO_DIVIDE | ORA-01476 | 试图用 0 作为除数。 |
CURSOR_ALREADY_OPEN | ORA-06511 | 试图打开一个已经打开的游标 |
结构类型:
exception
when [异常名称] then
--异常处理逻辑--
例如:
--变量的用法--
declare
v_price number(10,2);--单价
v_account T_ACCOUNT%ROWTYPE;--记录型
v_usenum2 number(10,2);--使用吨数
v_money number(10,2);--水费金额
begin
--对单价进行赋值
v_price:=3.45;
--赋值
select * into v_account from T_ACCOUNT
where year='2012' and month='01' and owneruuid=1;
--使用吨数
v_usenum2:= round(v_account.usenum/1000,2);
--计算金额
v_money:=v_price*v_usenum2;
DBMS_OUTPUT.put_line('单价:'||v_price||'吨数:' ||v_usenum2||'金额:'||v_money||'上月字数:'||v_account.num0||'本月字'||v_account.num1);
exception
when NO_DATA_FOUND then
--异常处理逻辑
DBMS_OUTPUT.put_line('SELECT INTO 语句中没有返回任何记录。');
when TOO_MANY_ROWS then
--异常处理逻辑
DBMS_OUTPUT.put_line('SELECT INTO 语句中返回多于 1 条记录。');
end;5、条件判断
8.5、条件
基本语法1
if 条件 then
业务逻辑
end if;
基本语法2
if 条件 then
业务逻辑
else
业务逻辑
end if;
基本语法3
if 条件 then
业务逻辑
elsif 条件 then
业务逻辑
else
业务逻辑
end if;
8.6、循环
-
无条件循环
loop --循环语句 end loop; --示例 输出冲1开始的100个数-- declare v_num number:=1; begin loop dbms_output.put_line(v_num); v_num:=v_num+1; exit when v_num>100; end loop; end ;
-
条件循环
while 条件 loop --循环语句 end loop; --示例 输出冲1开始的100个数-- declare v_num number:=1; begin while v_num<=100 loop dbms_output.put_line(v_num); v_num:=v_num+1; end loop; end ;
-
for循环
for 变量 in 起始值..终止值 loop --循环语句 end loop; --示例 输出冲1开始的100个数-- begin for v_num in 1..100 loop dbms_output.put_line(v_num); end loop; end;