数据库
DB (dataBase) 数据库 DBMS (dataBase Manger System) 数据库管理系统
关系型数据库 常见的数据库管理系统比如:mysql(免费,开源) Oracle(付费,支持windows,unix,Os等多种平台)\ sqlServer(微软,只能运行在windows)
非关系型数据库(数据在虚拟内存里) Redius
sql
sql 可以用来在关系数据库上执行数据操作
sql可分为:
``` 数据定义语言(DDL) CREATE 创建 ALETR 修改 DROP 删除 TRYNCATE 删除表数据
数据操纵语言(DML) INSERT 插入 UPDATE 更新 DELETE 删除
事务控制语言(TCL) COMMIT 提交 确认已经进行的数据改变 ROLLBACK 回滚 取消 已经进行的数据改变 SAVEPOINT 保存点 使当前的食事务可以回退到指定的保存点
数据查询语言(DQL) SELECT 查询
数据控制语言(DCL) GRANT 授予用户权限 REVOKE 收回用户或者角色的使用 CREATE USER 创建用户
```
数据库中事务是自动开始执行的,只要执行了DML语句那么事务就开始了
sql语句的本身不区分大小写,但是为了可读性关键字全部大写,非关键字全部小写
创建
创建仓库
创建仓库时不设置字符集,默认是系统的字符集
sql CREATE DATABASE 仓库名 CHARACTER SET 字符集
创建表
sql CREATE TABLE 表名 IF NOT EXISTS( 字段名 类型 [约束 默认值 字段说明] )
插入数据
sql INSERT INTO 表名 (字段名) VALUES (值)
复制添加
sql INSERT INTO 表名 (字段名) SELECT (字段名) FROM 表名
修改
修改字符集
sql ALTER DATABASE 仓库名 CHARACTER SET 字符集
修改字段名称
sql ALTER 表名 TABLE CHANGE 旧字段名 新字段名 类型
修改字段类型
sql ALTER TABLE 表名 MODIFY 字段名 新类型
修改表格数据
sql UPDATE 表名 SET 字段名= WHERE 限制条件
查询
查询当前使用的仓库
sql SELECT DATABASE()
查询表结构
sql DESC 表名
查询全部
sql SELECT * FROM 表名
查询部分
sql SELECT 字段名,字段名 FROM 表名
条件查询
```sql SELECT * FROM 表名 WHERE 条件 SELECT * FROM 表名 WHERE 条件1 OR 条件2 SELECT * FROM 表名 WHERE 条件1 AND 条件2 SELECT * FROM 表名 WHERE 字段名 BETWEEN MAX AND MIN; --模糊查询-- SELECT * FROM 表名 WHERE 字段 LIKE "%%%"
--空值查询-- SELECT * FROM 表名 WHERE 字段 IS NULL --去重查询-- SELECT DISTINCT 字段 FROM 表 --分组查询 根据指定的字段进行分组操作,字段中值相同的划分为一组-- SELECT 分组字段 , 聚合函数 FROM 表名 GROUP BY 分组字段
--分组查询后进行条件筛选--
SELECT 分组字段,聚合函数 FROM 表名 GROUP BY 分组字段 HAVING 条件
--排序查询(默认升序)--
SELECT * FROM 表名 ORDER BY 排序字段
-------降序--- SELECT * FROM 表名 ORDER BY 字段名 DESC
----多字段排序(根据字段1 进行排序,相同部分按照字段2 )---
SELECT * FROM 表名 ORDER BY 字段1,字段2,字段三
--分页查询--
SELECT * FROM LIMIT 0,10
---别名---
SELECT 字段名 AS 别名 FROM 表名; ```
函数查询
```sql -- 聚合函数 COUNT (*) --统计当前表格的记录 COUNT(字段名) -- 自动排除字段的null值
-- 表中某个字段的最大值 MAX(字段名)
-- 分组中,每组指定字段的最大值 SELECT MAX(字段名),分组字段 FROM 表名 GROUP BY 分组字段
-- 统计值之和 SELECT SUM(字段名) FROM 表名
-- 统计分组字段和
SELECT SUM(字段名),分组字段 FROM 表名 GROUP BY 分组字段
-- 平均值 SELECT AVG(字段名) FROM 表名
-- 分组字段平均值
SELECT AVG(字段) ,分组字段 FROM 表名 GROUP BY 分组字段
-- 空值替换函数
IFNULL(字段名,新值)
--查询字符串的字节长度
LENGTH(字段名)
-- 拼接字符串 CONCAT(字段名,字段名)
--字母转大写
UPPER(字段)
--字母转小写 LOWER(字段)
--字符替换 REPLACE(字段名,原有内容,新内容)
--截取字符串
SUBSTRING(字段名,起始下标(从1开始),截取长度)
```
数学计算
```sql -- 向上取整 CELL() -- 四舍五入 ROUND() -- 向下取整 FLOOR()
--求次幂 POW() ```
日期操作
```sql -- 获取当前日期 NOW() -- 日期加减 DATE_ADD(日期,INTERVAL 要加/减的日期 类型(DAY || YEAR || HOUR || MINUTE || SECOND
))
--获取日期的部分内容 DAY() YEAR() HOUR() MINUTE() SECOND()
--日期相差的天数 DATEDIFF(日期1,日期2)
-- 计算日期之间相差的各种数量
TIMESTAMPDIFF(类型,日期1,日期2)
-- 一年中的第几天 DAYOFYEAR(日期)
-- 一周中的第几天
DAYOFWEEK(日期)
-- 日期转字符串
date_format(日期,"%Y-%m-%d")
-- 字符串转日期
strtodate("日期字符串","%Y年%m月%d日") ```
多表查询
普通多表查询
```sql -- 无条件的多表查询(查询结果为笛卡尔积形式) SELECT * FROM 表名1,表名2
-- 条件连接查询
SELECT * FROM 表1,表2 WHERE 表1.字段(主键id) = 表2.字段(外键id)
-- 自连接查询 ```
连接查询
外连接查询(JOIN)
```sql -- 左连接 (left join) -- 左表中的数据全部展示,右表部分展示连接成功的信息,如果左表在右表中没有对应信息则右表部分用NULL填充 SELECT * FROM 表1 LEFT JOIN 表2 ON 表1.字段=表2.字段(连接条件) -- 右连接 (right join)
-- 右表数据全部展示,左表只展示和右表相关的部分 SELECT * FROM 表1 RIGHT JOIN 表2 ON 表1.字段=表2.字段 ```
内连接(inner JoIN)
```sql --只显示连接成功的信息
SELECT * FROM 表1 INNER JOIN 表2 ON 表1.字段 = 表2.字段 ```
全外连接(FULL JOIN ,在MYSQL中不支持)
sql SELECT * FROM 表1 FULL JOIN 表2 ON 表1.字段=表2.字段(条件) union all 默认是合并重复,加上unioc all会进行合并重复
子查询
```sql -- 子查询就是利用查询出来的数据,作为条件 ,就是一个查询语句中嵌套另外一个或者多个查询
-- in 关键字查询
-- 取in范围内的数据 SELECT * FROM 表1 WHERE 字段 in (SELECT 字段 FROM 表2 WHERE 条件)
-- not in
--取不在 in范围内的数据
SELECT * FROM 表1 WHERE 字段 NOT IN (SELECT 字段 FROM 表2 WHERE 条件)
-- int查询和not in查询在进行sql优化时,会被优化掉
-- exists 查询 (用来代替in使用)
SELECT * FROM 表1 WHERE EXISTS (SELECT * FROM 表2 WHERE 表2.字段=表1.字段)
--not exists 查询 (用来代替 not in使用)
SELECT * FROM 表1 WHERE NOT EXISTS (SELECT * FROM 表2 WHERE 表2.字段=表1.字段) ```
删除
删除仓库
sql DROP DATABASE 仓库名
删除表
sql DROP TABLE 表名
删除字段
sql ALTER TABLE 表名 DROP COLUMN 字段名;
删除表中部分数据
具有事务记录,在删除记录时可以找回
sql DELETE FROM 表名
清空表中所有数据
不具有事务记录,清空的数据无法找回
sql TRUNCATE TABLE 表名
约束
约束就是字段下的值添加限制条配件,分别是:
非空约束(不能为空 NOT NULL)
唯一约束(不能出现重复的值 UNIQUE)
主键约束(PRIMARY KEY ,非空且唯一,一张表中只能有一个主键)
外键约束(FOREIGN KEY REFERENCES 关联表名(关联字段) 外键约束是建立量表之间的关联,外键约束所在的表称为从表,依托的表称为主表)
检查约束(在MYSQL中不支持)
自增约束(AUTO_INCREMENT)
默认值约束 (default 值)
数据库的三大范式
设计良好结构的数据库,减少数据冗余
第一范式
同一列中不能有多个值(保持数据的原子性),字段表意明确
第二范式
满足第一范式的基础上,非主键属性,必须与主键属性做关联,必须是同一个整体的直接字段
第三范式
在满足第二范式的基础上,在实体中不存在非主键属性传递函数依赖于主键属性
用户权限设置
创建用户
```sql CREATE USER "用户名"@"IP" IDENTIFIED BY "密码"
-- % 表示所有IP ```
授权
sql GRANT 权限 ON 数据库.* to "账号"@"IP"
收回权限
sql REVOKE ALL/表名 ON 数据库.* FROM "用户名"@"IP"
查询权限
sql SHOW GRANTS FOR "用户名"@"ip"
删除用户
sql DROP USER "用户名"@"IP"
索引
索引可以提高sql的查询效率,索引能够提高查询效率,但是会降低增删改的效率,因此不能够降低过多的索引。应该给经常作为查询条件的字段作为主键索引和唯一性索引。
主键约束和唯一性约束会自动创建索引
```sql -- 创建索引 CREATE INDEX 表名 索引名(字段) -- 查看当前表中的索引 SHOW INDEX FROM 表名
-- 删除索引 ALTER TABLE 表名 DROP INDEX 索引名 ```
视图
视图的作用简化,复杂查询。
视图的本质就是把一条查询语句 保存到数据库中,下次可以直接使用名称调用该sql语句
```sql -- 创建视图
CREATE VIEW 视图名 AS 查询语句
-- 利用视图查询案例
CREATE VIEW demo AS SELECT * FROM student WHERE name="小";
SELECT * FROM demo WHERE id<10;
-- 如果视图中查询的字段都是表中存在的字段时,且是一个单表拆箱语句时那么该视图是一个简单视图,简单视图在不违反表中约束的情况下,可以进行数据的增删改查,最终映射到源表中
-- 如果查询语句为多表查询语句或者函数查询称为复杂视图,不能进行数据增删改查
```
横表
把每项信息作为字段名,每一行可以展示完整额个体信息。 就是一行展示所有信息,横表的结构较为复杂,一行展示一个实体记录
优势: 数据展示清晰
劣势: 表结构复杂
纵表
普通的建表形式即为纵表形式
优势 : 结构扩展方便
劣势: 数据结构不清晰
事务
事务具有四个特性:
原子性:一组sql语句做为一个整体,要么全部成功,要么全部失败
一致性: 事务操作前和事务操作后必须保持事务一致性(即必须满足源表中的约束和类型定义)
隔离性: 把每个事务操作进行隔离,形成独立的整体,防止事务之间相互影响
持久性:事务提交后,所有操作需要永久的更改。
```sql -- 开启事务 Begin
-- 回滚事务 rollback
-- 提交事务 COMMIT
-- 保存点
SAVEPOINT 保存点名
-- 回滚至保存点 ROLLBACK TO 保存点名 ```
事务的隔离级别
脏读
一个事务读取了另外一个事务没有的提交的数据,非常严重,必须排除掉
不可重复读(update)
一个事务读取另外一个提交过的数据,造成另外一个事务,多次读取的内容不一致,数据的内容改变
幻读(虚读)(Insert || Delete)
一个事务读取另外一个事务已经提交的数据,但是这里面强调的是数据数目的改变
数据库的事务隔离级别
Serializable 可避免脏读,不可重复读,虚读的情况(可串行化,一个事务一个事务运行,运行效率慢)
Repeatable 可避免脏读,不可重复读情况的发生 (可重复读) 不可以避免虚读
Read Committed 可避免脏读情况发生 (读已提交,避免不了虚读已及不可重复读)
Read uncommitted 最低级别,以上情况均无法保证
设置【读未提交】隔离级别 (Read uncommitted)
sql SET SESSION TRANSACTION ISOLATION LEVEL 级别名称
JDBC操作事务
java //取消自动提交事务 connection.setAutoCommit(false); //开启 conn.begin(); //提交 conn.commit(); //回滚 conn.rollback
MYSQL相关八股文
MYSQL的架构分为两层 : Server 层和存储引擎层
存书引擎层负责数据的存储和提取 Server层负责建立连接,分析和执行SQL语句
关于存储引擎可以参考另一篇存储引擎。
mysql是用c和c++来进行实现的,所一对于mysql的话其本质也是一套IO的操作,关于c++的IO操作可以参考另一篇c++面向对象笔记(包含IO操作demo)
执行一条SELECT 语句时是怎样的
1.连接器 用户使用mysql的时候首先是需要通过输入命令进行连接Mysql,mysql的服务使用户可以通过mysql服务与mysql进行通信(mysql是基于TCP协议进行传输的也会经历三次握手)。mysql的连接也包含长连接和短连接的概念。但是mysql的查询是使用临时的内存管理连接对象,这些资源只有在断开连接时才会被释放,如果占用内存较大则会被系统杀掉,所以解决的方式就是,定期断开长连接,或者是当用户执行了很大的操作后调用mysql_reser_connection函数进行刷新操作刷新之后会回复到连接时的操作
2.查询缓存,在server层会有一次查询缓存的操作。查询缓存的操作就是去缓存里查找当前的sql语句的,如果有的话则返回缓存中的结果,如果没有则继续向下执行。查询缓存是以key(SELECT语句)-value(查询的结果)的形式存储的。但是如果在查询之后该表有更新操作那么查询缓存就会被清空,所以相对于更新次数比较多的表的话查询缓存基本上就没起到作用,所以在8.0版本往后就去掉了。
3.解析sql,解析sql主要就做两件事判断sql语句有没有错,首先就是提取出来关键字,判断关键字是否正确,以及sql语句是否合乎规则,如果不合乎规则会报错,关于表或者字段不存在会在执行sql的时候进行报错
4.执行sql,执行sql的时候会先去进行判断SELECT语句中的表或者字段是否存在这是是在预处理阶段。经过预处理阶段后,会给SELECT语句制定一个执行计划,这个工作是优化器来完成的,优化器主要负责将sql语句的执行方案确认下来,就是确认使用哪个索引。经历过优化器后,就确定的执行方案,接下来就是由执行器和存储引擎进行交互了,交互就是根据确认下来的执行方案从存储引擎读取方案。
Oracle数据库
系统可移植好:收费,功能强,分布式数据库。 大型数据库,关系型数据库,
结构划分: oracle数据库 数据库管理系统 oracle实例 数据库实例,是一组用于管理数据库问件的内存结构
使用sql命令进行数据库操作的。
oracle 是通过表空间来管理数据文件的
增加
创建表空间
sql CREATE TABLESPACE 空间名 DATAFILE 对应的数据文件(路径/文件名.dbf)
创建表
如果未指定空间名,则表创建在用户的默认表空间中, 字段命名规范,不能数字开头,不能使用-,不能超过30个字符,只能包含A-Z,a-z,0-9,\$,# ,不能使用关键字
sql CREATE TABLE (字段名 类型 约束) TABLESPACE 表空间名
修改
扩展数据文件存储大小
指定空间数据文件
自增文件大小
修改默认表空间
主键自增
oracle没有主键自增,所以需要借助创建序列来是实现主键自增
```sql CREATE SEQUENCE 序列名 INCREMENT BY 每次增加值 START WITH 起始值 MAXVALUE 最大值 NOCYCLE NOCACHE; -- 在插入数据时,遇到id自增使用序列
序列名.NEXTVAL ```
查询
查询系统字符集
sql SELECT sys_context("userenv","language") FROM dual;
查询所有的表空间
sql SELECT * FROM DBA_TABLESSPACES;
查询表空间下的数据表
sql SELECT * FROM DBA_TABLES WHERE TABLESPACE_NAME="表空间名"
查看所有用户的默认表空间
sql SELECT username,DEFAULT_TABLESPACE FROM DBA_USERS ORDER BY username
查看当前用户的默认表空间
sql SELECT * FROM user_users
删除
用户操作
切换账号
sql connect sys/admin as sysdba
查看当前用户
sql SHOW USER
创建用户
sql CREATE USER 用户名 identified by 密码
用户授权
系统权限(创建表,创建用户等)
角色权限 (oracle 已经定义好的角色 [连接角色(connect),基本操作角色(resource)],自定义角色)
对象权限 (对数据进行增删改查)
授予系统权限
sql GRANT 权限1,权限2 TO 用户名
查询用户包含的系统权限
sql SELECT * FROM
授予对象权限
这里的方案名,指的就是创建该表的用户名
sql GRANT 权限 ON 方案名.数据表名 TO 用户名(被授予用户)
查询其他用户创建的表
sql SELECT * FROM 方案名.表名
权限收回
sql REVOKE 权限 ON 方案名.表名 FROM 用户名
允许权限传递
sql GRANT 权限 TO 用户名 WITH ADMIN OPTION
权限传递
sql GRANT 权限 TO 用户名
赋oracle已经有的角色
创建自定义角色
sql CREATE ROLE 角色名
角色赋予权限
sql GRANT 权限1,权限2 TO 角色名
赋予用户角色
sql GRANT 角色名 TO 用户名
锁定用户
sql ALTER USER 用户名 ACCOUNT LOCK
解锁用户
sql ALTER USER 用户名 ACCOUNT UNLOCk
视图
作用:简化查询
分类:简单视图: 可以进行增删改
复杂视图: 只能进行查询
创建视图
sql CREATE 视图名 VIEW as 查询语句
索引
提高查询效率
创建索引和删除索引,参考mysql的索引
事务
事务(参考mysql的事务) oracle里的事务需要手动提交
PLSQL编程
过程处理语言
有三个模块
declare 声明模块
begin 执行模块
exception 异常处理
end 结束
```sql -- Hello World
-- 打开输出流 set serveroutput on; -- begin begin dbmsoutput.putline('hello,world'); end; / --/表示编译并执行
```
声明变量
变量命名规范: 变量使用 v_ 开头 常量使用 c_ 开头 异常变量使用 _exception 后缀 游标变量 _cursor 后缀
声明变量,使用declare
```sql --声明变量
declare
变量名 类型 := 初始值, 变量名2 类型 :=初始值
-- := 赋值运算符 ```
INTO 子句
INTO 子句用于将查询结果赋值为变量
```sql declare VID NUMBER(10); VNAME VARCHAR(20); BEGIN SELECT 字段1,字段2 INTO VID,VNAME FROM 表; END;
-- 字段1就是VID的值,字段2 就是VNAME的值,纯序要一样而且数据类型一致 -- 且这种赋值方式,查询结果只能有一行
--动态类型设定 DECLARE vID 表名.字段名%TYPE VNAME 表名.字段名%TYPE
--这样就实现了动态类型绑定,当表中的数据类型改变时变量的类型也随之改变 ```
变量的类型
变量的类型有三种:
标量类型(数据库中的基本类型)
复杂类型
游标类型
复杂类型的变量声明
复杂类型的变量声明有两种: 自定义类型 table类型
```sql DECLARE -- 声明自定义类型 TYPE 自定义类型名 IS RECORD ( 变量名 表名.字段名%TYPE )
--使用自定义类型声明变量
变量名 自定义类型名;
--输出
BEGIN SELECT 字段名 INTO 变量 FROM 表名; DBMSOUTPUT.PUTLINE(变量.字段); ```
游标类型(CURSOR)
标量类型和复杂类型只能用于接收单行结果,然而游标类型就是用来接收多行结果的
游标类型又分为两种:
显示游标(静态游标) 声明时直接指定游标类型存储的内容
隐式游标 (动态游标) 声明时不指定对应的语句,在指定时才指定语句
显示游标
```sql DECLARE CURSOR 游标名_cursor is 查询语句; --接收到结果以后需要遍历输出,但是每次遍历的结果需要被变量接收所以需要提前声明变量 变量名 表名.字段名%TYPE
BEGIN
--打开游标
OPEN 游标名_cursor;
--开始遍历游标
LOOP --oracle的循环语句
--FETCH关键字用于抓取每一行结果
FETCH 游标名_cursor INTO 变量名; -- 此处的变量名就是,提前在DECLARE提前声明的存储结果的变量
--遍历结束条件,如果未抓取到数据则退出 EXIT WHEN 游标名_cursor%NOTFOUND;
--处理抓取到的内容
DBMSOUTPUT.PUTLINE(变量名) END LOOP;
--关闭游标
CLOSE 游标名_cursor ```
隐式游标
```sql DECLARE --自定义一个游标类型
TYPE 类型名 IS REF CURSOR;
--以自定义类型声明变量
变量名1 自定义类型名
--提前定义变量,用于存储遍历的每一项
变量名2 类型
BEGIN
--打开游标
OPEN 变量名1 FOR 查询语句
--遍历游标
LOOP
--抓取每一行结果
FETCH 变量名1 INTO 变量名2;
--遍历结束条件
EXIT WHEN 变量名1%NOTFOUND;
--处理遍历结果
--关闭游标 CLOSE 变量名1;
END; ```
声明常量
常量赋值之后,不可再改变
常量声明使用 CONSTANT关键字
sql DECLARE c_常量名 CONSTANT 类型 :=初始值
流程控制
IF语句
```sql -- 单个if IF 条件 THEN 符合条件的执行内容; END IF;
-- if -else
IF 条件 THEN 符合条件的执行内容
ELSE 不符合条件的执行内容
END IF;
--if -else if -else
IF 条件1 THEN
满足条件1执行的内容
ELSIF 条件2
满足条件2指定的内容
ELSE
条件都不满足执行的内容
END IF; ```
case语句
```sql CASE 变量
WHEN 值1 THEN
执行语句;
WHEN 值2 THEN
执行语句;
END CASE
```
LOOP循环
```sql LOOP --结束条件 EXIT WHEN 条件
--循环内容 END LOOP ```
FOR循环
在这里FOR 循环的底层就是LOOP循环
```sql --正循环 FOR 循环次数变量(i) IN 最小值..最大值 LOOP --循环体 END LOOP
--反转循环
FOR 循环次数变量(i) IN REVERSE 最小值..最大值 LOOP
--循环体
END LOOP ```
WHILE 循环
WHILE循环的底层也是LOOP
```sql WHILE 条件 LOOP
-- 循环体
END LOOP ```
NULL关键字
在PLSQL编程的循环结构里,满足条件之后必须有执行内容,如果没有执行内容会抛出异常。
为了避免抛出异常有了NULL关键字
如果没有执行内容,用NULL去代替
存储过程(procedure)
存储过程就是用来存储执行过程的
```sql --创建存储过程 CREATE OR REPLACE PROCEDURE 过程名(参数1 参数类型) IS --这里的参数类型不需要写长度 -- DECLARE 声明模块(需要声明变量则先写声明模块) BEGIN -- exception (有异常,进行异常处理) END; / -- 存储过程没有返回值
--存储过程的调用需要在代码块中调用 过程名(参数);
-- 创建有内容输出的存储过程
CREATE OR REPLACE PROCEDURE 过程名(参数1 IN 参数1类型,参数2 OUT 参数2类型) IS --IN表示的是输入参数,In可以省略,OUT表示的是输出参数OUT不可以省略 BEGIN --给输出参数赋值 END; /
--在调用时,在参数位置接收 DECLARE
变量1 变量1类型 过程名(参数1,参数2,变量1); --这样调用变量1就获取到了过程的输出参数 END; / ```
函数
函数有返回值且函数必须设置返回值
sql --创建函数 CREATE OR REPLACE FUNCTION 函数名(参数 参数类型) RETURN 返回值类型 IS BEGIN END; /
查询当前用户的所有存储过程和函数
sql SELECT * FROM USER_PROCEDURES
删除存储过程和函数
```sql DROP PROCEDURE 过程名
DROP FUNCTION 函数名 ```
包(package)
对存储过程和函数进行整合
包规范 (包规范就是规定包中存储的内容)
sql CREATE OR REPLACE PACKAGE 包名 IS FUNCTION 函数名(参数) RETURN 返回类型; PROCEDURE 过程名 (参数); TYPE 类型名 IS REF CURSOR --自定义类型 END; --包规范创建结束
包主体 (包主体就是包规范的实现类)
sql CREATE OR REPLACE PACKAGE BODY 包名 IS --包规范的实现 END; --包主体创建结束
```sql /** Demo */
/** 包规范 */
CREATE OR REPLACE PACKAGE TEST_PACKAGE IS
PROCEDURE INSERT_TEST(ID NUMBER,NAME VARCHAR);
PROCEDURE DELETE_TEST(ID NUMBER);
PROCEDURE UPDATE_TEST(ID NUMBER,NAME VARCHAR);
TYPE PLSQL_CURSOR IS REF CURSOR;
FUNCTION FINDALL RETURN PLSQLCURSOR;
END;
/** 包主体 */
CREATE OR REPLACE PACKAGE BODY TEST_PACKAGE IS
PROCEDURE INSERTTEST(ID NUMBER,NAME VARCHAR) IS BEGIN INSERT INTO PLSQL VALUES (ID,NAME); DBMSOUTPUT.PUT_LINE('SUCCESS INSERT'); END;
PROCEDURE DELETETEST(ID NUMBER) IS BEGIN DELETE FROM PLSQL WHERE ID=ID; DBMSOUTPUT.PUT_LINE('DELETE SUCCESS'); END;
PROCEDURE UPDATETEST(ID NUMBER,NAME VARCHAR) IS BEGIN UPDATE PLSQL SET NAME=NAME WHERE ID=ID; DBMSOUTPUT.PUT_LINE('UPDATE SUCCESS'); END;
FUNCTION FINDALL RETURN PLSQLCURSOR IS RESULTCURSOR TESTPACKAGE.PLSQLCURSOR; BEGIN OPEN RESULTCURSOR FOR SELECT * FROM PLSQL; RETURN RESULT_CURSOR; END;
END;
/** 调用 */
BEGIN
TEST_PACKAGE.INSERT(10,'王老七'); END; / ```
查询包和删除包
sql DROP PACKAGE 包名
异常
异常分为预定义(ORACLE定义好的异常)和非预定义异常(有异常编号没有异常名)以及自定义异常
捕获预定义异常并处理
关于ORACLE预定义异常,可以查看plsql 预定义异常文档
```sql EXCEPTION WHEN 异常名 THEN
异常处理
```
捕获非预定义异常
```sql EXCEPTION WHEN OTHERS THEN 异常处理
```
给非预定义异常命名
sql DECLARE 异常名 EXCEPTION PRAGMA EXCEPTION_INIT(异常名,异常编号); BEGIN EXCEPTION WHEN 异常名 TEHN 异常处理
自定义异常
sql DECLARE 异常名 EXCEPTION BEGIN IF 条件 THEN RAISE 异常名 --使用RAISE抛出异常 END IF EXCEPTION WHEN 异常名 TEHN RAISE_APPLICATION_ERROR(异常编号,异常提示信息) -- RAISE_APPLICATION_ERROR方法用于输出异常信息 END;
序列和触发器
ORACLE没有AUTO_INCREMENT所以通过序列或者触发器来实现主键自增
创建序列
sql CREATE SEQUENCE 序列名 INCREMENT BY 增加值 START WITH 起始值 MAXVALUE 最大值
创建触发器
触发器就相当于是监听事件
```sql CREATE OR REPLACE TRIGGER 触发器名 DELETE|| UPDATE || INSERT AFTER||BEFORE ON 表名 FOR EACH ROW -- FOW EACH ROW 可加可不加,如果不加就是执行一行语句触发一次,加就是每一行受到影响就触发一次
BEGIN 触发之后的操作 END; ```