技术交流


PLSQL基础学习笔记

Mar 6, 2019 4:38:15 PM
132
1

基本概念

关系型数据库三范式

1、字段必须有单一属性,不可拆分。

2、表具有唯一性的主键。

3、表中的字段不能包含其他表中已出现的非主键字段。

sql分类

1、DML:数据操纵语言,完成数据的增删改查。

2、DDL:数据定义语言,创建修改表、视图、过程及用户等。

3、DCL:数据控制语言。

4、DBA:数据库管理员。

plsql语言

plsql都是有语句块组成,块与块之间可以嵌套。每个块中可以包含多条sql,大大减少了网络开销。

plsql执行环境

plsql块被数据库内部的plsql引擎处理,plsql引擎块的sql语句交给sql引擎处理。

1、服务器端的sql引擎:plsql客服端发送sql语句块给数据库服务器,服务端sql引擎对语句块进行处理,块中的sql语句交给sql执行器来执行。

2、客服端的plsql引擎:客服端的plsql引擎直接执行块中的过程性语句,但如果plsql语句块中的包含sql语句或存服务器端储过程的调用,就需要将这些调用传给服务端,用服务端的sql执行器或plsql引擎执行。

plsql块组成

DECLARE     --可选

  --定义部分

BEGIN    --必须

  --执行部分

EXCEPTION   --可选

  --异常处理部分

END;     --必须

注意:内部嵌套块可以访问外部快定义的变量,但外部块不能访问内部块定义的变量。

变量和类型

plsql四种变量类型:

1、标量变量:存放单个数值的变量,如日期、时间。

2、复合变量:存放多个值的变量,有plsql符合数据类型定义,如plsql记录,plsql表、嵌套表。

3、参照变量:用于存放数值指针的变量,如游标和对象标量。

4、LOB变量:用于存放大批量数据的变量。

变量

声明

v_name  [constant]  type  [not null]  [:= value];

constant --声明常量

value --初始值

一旦出现not null或声明常量时后面必须赋一个初始值。

赋值null做任何运算,结果为null。在变量没有赋值之前不要直接使用变量进行变量运算。

使用%type:基于已有的变量类型或数据库列类型来指定变量的类型。如:变量%type

使用%rowtype:绑定变量类型为数据库整行类型。如:v_a  emp_table%rowtype

作用域:如果块中定义了与外层块中相同的变量,使用“外层块名称.变量”这样的限定名称来获取外层变量。

数据类型

字符类型

9006b65b-b4a3-4c36-a99a-c81bea56d14c

数字类型

e80301d7-0c06-4b61-a3b0-bbe97ae1737a

日期时间类型

1、date:表示年月日时分秒。可以使用to_dateto_char函数在日期和字符串之间转换。

2、timestamp:表示年月日时分秒(包括秒的小数部分)。

3、timestamp with time zonetimestamp带时区。

4、timestamp with local time zone:使用数据库时间。

5、interval类型:

用于存储两个时间戳之间的间隔。两种定义方式:

1)interval year to mounth:年月之间的时间间隔。

2)interval day to second :天数,时分秒之间的时间间隔。

布尔

LOB类型:最大可存4G

d6513e51-6df8-4b8c-9e3f-f7da95b9f027 

引用类型:

1、refcursor:引用游标。如:v_x  sys_refcursor

2、ref:指向对象类型的实例指针。

用户自定义子类型:

语法:subtype 子类名称 is 基类名称[约束] [not null];

子类型可以继承基类型大小约束,不能继承其他约束(not null)。

程序控制语句

1、条件控制:

if-then-else-end if    --else在条件值为falsenull是执行。

case-when-then-when-then-end case等于if-then-elsif-end if

2、循环控制语句:

1)简单循环:包含loop-end loop和用来退出循环的exit方法。

2)数字for循环:循环带指定次数退出循环。

3)while循环:当条件成立时执行循环。

3goto语句:无条件跳转语句。

过程函数和包

它们都是plsql语句块中的命名块。,过程和函数统称为子程序。过程和函数具有如下特点:

1、都具有名称,可以接受传入和传出参数。

2、都具有声明部分、执行部分和异常处理部分。

3、在使用前或被编译保存到数据库中。

函数和过程最大区别是函数具有返回值,过程没有返回值。

包是一个逻辑单位,包分为包规范部分和包体部分。包规范部分用create package语句创建,相当于接口,用于声明常亮、变量、游标、子程序等;包体部分用create package body语句创建,用于实现包规范部分声明的子程序和游标。

触发器

触发器不能显示的被调用,而是在数据库发生特定事件时隐式执行,并且不接受任何参数。

结构化异常处理

plsql异常出来块用EXCEPTION开始。EXCEPTION采用when-then-when others then进行异常处理筛选。

集合与记录

记录类型

    允许多个不同类型的变量当做一个整体处理。类似于数据库中的一条记录。先定义记录类型,在声明记录类型变量。

集合类型

允许数据类型相同的多个变量当做一个整体进行处理,类似于数组。plsql三种集合类型:

1、关联表:又称索引表。元素个数不限,索引可为负数,字符型。

2、嵌套表:下标从1开始,个数不限。嵌套表的类型可以作为表列的数据类型使用。在使用嵌套表之前必须使用构造函数进行初始化。

3、变长数组:类型可以作为表的数据类型使用,下标从1开始,对元素个数有限制,使用前必须用构造方法初始化。

游标

一个指向上下文区域的指针。游标分为两种:

1、隐式游标:由plsql自动为DML语句或select-into语句分配的游标。

2、显示游标:在plsql声明块中显示定义,用来处理返回多行数据查询的游标。

可以使用open打开游标,使游标指向第一行;fetch检索当前行信息,并把游标指向下一行;close语句用来在游标移到最后一行关闭游标。

动态sql

在运行时由字符串拼接而成的sql,然后使用EXECUTE IMMEDIATE来执行动态拼成的sql

编码规范

1、标识符命名不超过30个字符。

2、如果字符串中包含双引号,可以使用两个双引号代替。如字符串Im jack可表示为I’’m jack

33空格缩进法。

4、标识符命名规则:前缀_标识符内容_后缀。标识符命名建议表:

f84c6ce4-af33-4ef5-a7df-2f51b1b8854a

开发基础

数据表管理

数据定义语言DDL

1、create语句: create table

2、alter语句:

alter table 表名 add 字段 字段类型 字段约束;

alter table 表名 drop comumn 字段;

alter table 表名 rename column 原列明 to 新字段名;

3、drop语句: drop table 表名;

创建副本表

语法:create table 附表 as select from 原表 [where 1 = 2] --有这个where条件表示只创建表结构,没有数据。

注意:

1、不能复制约束条件及默认值。

2、不能为新表指定空间。

3、一些大对象数据(bloblong)的查询表不能创建成功。

创建约束

关键字:constraint。该关键字可以指定约束名,可同时用于多列。如:constraint 约束名 primary key (字段1,字段2...);

外键约束:[constraint 约束名] references 表名(字段) [on delete {cascade | set null}]; --on delete表是否级联删除。

检查约束:[constraint 约束名] check 条件;检查约束限制:

1、不能为视图指定检查约束。

2、检查约束不能包含子查询和标量子查询表达式。还有某些函数。

3、不能包含自定义函数。

4、不能包含伪劣。如:rownum、currval。

查询约束

约束信息可以从数据字典user_constraintsuser_cons_columns查看。

索引

创建索引时,会对索引字段排序,并获取每条记录rowid,生成索引条目(索引列值,rowid对应存到索引段)。where自居查询时,先对索引检索,再通过对应的rowid到表中读取数据。

创建索引:create [unoique/bitmap] index 索引名 on 表名(字段列表);

注意:创建复合索引时一般将最常查询的列放在最前面。建议大数创建b树索引,小数创建位图索引。

索引重命名:alter index 索引名 rename to 新索引名;

合并索引:alter index 索引名 coalesce;

重建索引:alter index 索引名 rebuild [tablespace 表空间];

说明:合并索引和重建索引都能消除索引碎片。但是合并索引不能转移表空间,代价低,只能在B树的统一子树合并,不改变树高度。

分配索引空间:alter index 索引名 allocate extent (size 容量大小); --防止索引段空间不足,动态扩容而降低装载速度。可以通过 alter index 索引名 deallocate unused多余索引空间。

删除索引:drop index 索引名;  对于唯一索引,如果是在定义时由oracle自动创建,可通过disable禁用约束或删除约束的方法来删除索引。

视图

创建视图:create or replace view 视图名 as 查询语句; --可以设置视图只读,指定修改或插入的行。

删除视图:drop view 视图名;

查询

dual

本身不具有任何意义,仅用来计算并返回结果。

rownum伪列

对结果动态集添加一个从1开始的序列号。

rowid伪列

它的值并没有存在表中,可以用它来删除重复数据。

交叉连接

1 cross join 2

自然连接

1 natural 2。自然连接只出现在两个表中具有相同名字和类型的列上。

联合查询

unionunionall:列数和列的数据类型一样。可在联合查询最后一句使用order by对结果排序。

相交查询

intersect:列数和列的数据类型一样。得到两个表去掉重复值的结果。

相减查询

minus:列数和列的数据类型一样。得到在查询一中存在,查询2中不存在的数据。

层次化查询

1、start with 条件1 connect by 条件2 --条件1可包含子查询;条件2不能包含子查询。

2、prior操作符。prior后的表达式将被当成当前列的父列进行计算。

3、level伪列。

数据操纵语言DML

插入数据

使用子查询插入向同一张表插入多条数据,如果目标表与查询的表结构一样使用:insert into 目标表 select * from...;目标表自插入子查询表的部分字段使用:insert into 目标表(字段列表) select 字段列表 from...

同时想多张表插入数据:insert {first | all} [when 条件 then] into [values(字段列表)]  [when 条件 then] into [values(字段列表)]... else into table[values(字段列表)] 子查询;

merge合并表行

merge into 表名 别名1 using |视图|子查询 别名2 on (关联条件) when matched then update set语句 when not matched then insert(字段列表)values(字段值列表);

序列

create sequence创建序列,主要工作是产生表的唯一值,序列存于数据字典,可以被多个对象共享。

序列只用在nextval对序列进行初始化后才能调用currval。使用nextval时会产生一个新的伪列,使用currval不会产生新的伪列。nextvalcurrval使用地方:

1、不是子查询一部分的select语句的字段列表。

2、insert语句中子查询的select列表。

3、insert语句中的values子句。

4、update语句中的set子句。

nextvalcurrval不能使用地方:

1、视图的select列表。

2、distinct关键字的select列表。

3、group byhavingorder by子句的select语句。

4、create tablealter tabledefault表达式。

使用alter sequence修改序列。

使用drop sequence 序列名删除序列。

同义词

同义词的目的是为了简化对目标对象的访问。同义词分为公用同义词和私有同义词。使用create [public] synonym 同义词名 for 要创建的同义词对象;使用drop sysnonym 同义词名;删除同义词。

记录与集合

记录类型

记录类型只是用来组织其他标量类型的容器,他本身没有值,他里面的每一个变量拥有自己的值。记录类型可以在plsql块的声明区、子程序或包的声明部分定义。

记录类型的定义:type 类型名 is record(字段名描述...);

记录类型的赋值:记录名.字段名 := ;

insert语句使用记录:insert into 表名 values 记录名;

returning子句中使用记录:在DML语句中包含一个returning语句,用来返回insertdeleteupdate影响的行。如:insert...returning 字段列表 into 记录名。记录变量不允许出现在select列表、where子句、group by子句、order by子句中。

集合

索引集合

定义:type 索引表名 as table of  plsql 预定义类型 [not null] index by 索引类型;

操纵:索引表名(索引) := 值。

嵌套表

定义:type 嵌套表名 as table of 元素类型 [not null]; --元素类型不能是booleanncharnvarchar2nclobref cursor。变量名 嵌套表名 := 嵌套表(值列表);声明初始化嵌套表。

“嵌套表名 is null”判断嵌套表是否被初始化。“嵌套表名(数字)”获取对应值。用delete删除嵌套表中的元素。

数据库中的嵌套表:用create or replace type 嵌套表名 as table of 元素类型 [not null];”创建。

变长数组

定义:type 数组名 {varray|varying array} (最大长度) of 数据类型 [not null];如:type alist is varray(50) of varchar(20)。可以通过extend扩展元素,但能超过最大长度。数据库中的变长数组:create or replace type 数组名 {varray|varying array} (最大长度) 数据类型 [not null]

基本结论:元素较少,优先考虑索引表;如果要存到数据库中,使用嵌套表;如果元素个数固定,使用变长数组。

集合方法

集合方法只能在plsql中使用,不能在sql语句中使用。调用方式:集合变量名.集合方法[(参数)]

exists方法:判断集合中指定元素是否存在。

count方法:返回集合的长度。

limit:返回集合元素的最大长度。对于嵌套表和索引表来说,最大长度不限,总是返回null

firstlast:返回集合第一个和最后一个元素的索引数字。如果集合为空,返回null

priornextprior返回特定索引值参数前一个元素的索引值,next返回特定索引值参数后一个元素的索引值。如果没有返回null

extendextend在末端加一个空元素;extend(n)在集合末端加n个空元素;extend(n,i)把第i个元素复制n份,加到集合末端。

trim:从嵌套表或变长数组删除尾端元素。trim从集合末端删除一个元素;trim(n)从集合末端删除n个元素。

delete:删除索引表或嵌套表一个或多个元素。delete删除所有元素;delete(n)删除第n个元素,如果索引为字符串,对应键值的元素会被删除。delete(m,n)删除mn的元素。

集合异常

COLLECTION_IS_NULL:调用一个空集合的方法。

NO_DATA_FOUND:小编索引指向一个不存在的索引。

SUBSCRIPT_BEYOUND_COUNT:下标索引值超过集合中的元素个数。

SUBSCRIPT_OUTSIDE_LIMIT:下标索引超出允许范围。

VALUE_ERROR:下标索引为空,或不能转换成正确的键类型。

批量绑定

使用批量绑定一次性向sql引擎发送多条sql,提升sql执行效率。批量绑定语法:forall 集合下标 in 起始索引...结束索引 sql语句; --集合索引连续。

BULK COLLECT

批量地从sql引擎中批量接收数据到一个集合,可以在collect intofetch intoreturning into子句中使用。...BULK COLLECT INTO 集合名[,集合名]...

使用的一些限制:

1、索引不能为字符串。BULK COLLECT INTO

2、只能在服务器端使用。

3、BULK COLLECT INTO目标对象必须是集合。

SQL内置函数

分析函数

基本语法function_name() over();

分析函数名

1)等级函数:用于寻找前n种查询。ROW_NUMBER()行号;RANK()DENSE_RANK()排名。

2)开窗函数:用来进行累计值计算。与分组函数同名。

3)制表函数:函数名与开窗函数相同;区别在于制表函数不能指定一个本地窗口,因此只是在整个分区或整个组上产生相同的结果(少了order by子句)。

4)LAGLEAD:允许在结果集中向前或向后检索值。可用于避免数据的自连接。

5)其他统计函数:VAR_POPVAR_SAMPSTDEV_POP等。用于计算任何未排序分区的统计值。

分区子句

使用partition by关键字将结果集分为n组。

排序子句

order by子句用于指定分组中数据的排序方式,排序方式会影响查询结果。分析函数的order by子句只能对各个分组进行排序,不能对查询结果排序。

开窗子句

开窗子句定义在order by子句之后,用来定义一个变化和固定的数据窗口方法,分析函数对这些数据进行操作。

分析函数可用于如下场景:

1、从当前记录开始到某个部分的最后一条记录。

2、在统计时可以统计分组以外的记录。

3、在当前的前几行或后几行进行滚动计算。

分析函数列表

1、firstlast函数:first函数从DENSE_RANK返回的集合中取出排在第一的行,last函数与之相反。使用语法:“分组函数 KEEP(DENSE_RANK FIRST ORDER BY...)”。

2、first_valuelast_value函数:分别用来返回over子句查询的第一条记录和最后一条记录。

3、laglead函数:lag的功能是返回指定列coln1行的值,如果超出范围则返回n2,如果没有指定n2则返回null,如果不指定n1则默认为1lead函数与之相反。lag(col[,n1][,n2]) over()

4、ntile() over():可以实现按层次查询。

游标

游标只是一个指向查询结果的指针。当游标打开后,数据被接收到一块内存区域存储,直到游标关闭。游标实际上指向的是一块内存区域,这块内存区域位于进程全局区内部,称为上下文区域。上下文区域一般保存:查询返回的数据行;查询所处理的数据行号;指向共享池中已分析的sql语句。

分类

显示游标:用cursor语句显示定义的游标,游标被定义之后需要打开并提取游标。

隐式游标:每个不属于显示游标的是sql DML语句都会创建一个隐式游标。隐式游标是动态创建的,因此不能显式的打开、关闭或提取一个隐式类型的游标,能是隐式打开、关闭或提取。允许关键字SQL来访问游标属性。通过%FOUND%ISOPEN%NOTFOUND%ROWCOUNT来访问右边相关属性(如:SQL%NOTFOUND和显式游标名%NOTFOUND)。

定义游标

通常使用显式游标来处理select语句返回的多行数据。定义方式:“cursor 游标名 [参数列表] [return 返回类型] is 查询语句 [for update [of (字段列表)] [NOWAIT]]”。

游标名只是一个标识符,不能把一个值或赋给游标名或在表达式中使用它。游标和变量有同样的作用域规则。使用显式游标用fetch语句提取数据。

游标的形式参数都是in模式,不能加not null约束,调用open 游标名(实参)。游标一旦打开就有指针指向第一行数据,然后就可以用fetch语句对数据进行提取。

数据提取

语法:fetch 游标 into 变量名列表 | 记录类型”、“fetch 游标 bulk collect into 集合变量”。

close 游标名”关闭游标。

游标的操作

loop循环:一般包含fetchexit when这两个子句。

游标for循环:使用for循环不用显式的打开、提取和关闭游标。

修改游标数据

1、for update子句:for update [of (字段列表) [nowait]]of (字段列表)为字段添加互斥锁。nowait值当相同行被锁定时,select update for将不进行等待而直接返回。

2、where current of 游标名:在使用for updat锁定了表的行后,可以在updatedelete语句中使用该子句来得到当前游标检索出来的行。

游标变量

游标类型的声明type 游标类型名 is ref cursor [return 游标类型]。声明完后将游标类型赋给游标变量。

打开游标变量:open 游标名 for 查询语句。如果type语句中没有指定return子句,则可以连续打开多次,分别为其赋不同的select语句。

控制游标变量:fetch 游标变量名 into 记录名 | 变量列表。

可以在包中声明游标类型,不能在包中声明游标变量。

事务处理

事务的属性

1、原子性

2、一致性

3、隔离性

4、持久性

commit提交事务

commit事务会结束数据库事务。如果数据库使用了DML语句对数据进行了修改,那么这些修改会保存到数据库。加在事务上的所有锁及事务所占用的一切资源(游标、内存等)会被自动释放。

commit声明:commit [work] [comment 50位以内的字符串]

rollback回滚事务

rollback中止事务,相当于撤销操作。误操作或异常可使用rollback回滚。

rollback基本语法:rollback [work] [to [savepoint] 保存节点名]to子句回滚到某个保存节点。

保存节点声明:savepoint 节点名。使用rollback to savepoint语句会发生:保存节点后的操作会撤销,但保存节点未被释放,如果需要,可以再次撤销该保存节点;该保存节点后的sql的锁和资源会被释放;整个事务并没有结束,sql处于挂起状态。

set transaction设置事务属性

允许开启一个只读或只写的事务,建立隔离级别或为当前事务分配一个特定的回滚段。该语句只能出现在事务第一句。

声明语法:set transaction 参数。具体参数如下:

1、read only:用于指定只读事务。任何修改都是非法的,不用指定回滚。查询过程不能使用for update子句。

2、read write:建立读写事务。

3、isolation level:用来设置事务的隔离级别。用法:set transaction isolation level seriallzation,设置序列隔离级别。set transaction isolation read comitted设置读提交隔离级别。set transaction isolation use rollback segment 回滚段名,给事务指定一个合适的回滚段。

锁定

表锁定

对整个表实行锁定,防止其他会话或事务对表访问造成冲突。用于保护整张表数据。表锁定不会阻止用户对表的查询,查询也不会获取表锁。只有两个事务对修改统一数据是才会出现一个等待另一个事务的情况。

使用表锁定的几种模式:

1、row share:行共享锁,允许用户并发查询和修改表的数据。不允许任何事务独占式的进行写访问。

2、row exclusive:行排他锁,与共享锁不同的是不能阻止别的事务对同一表的手工锁或独占式的读写。

3、share lock:共享锁,只允许别的事务查询或锁定特定的记录。防止数据修改。share

4、share row exclusive:共享排他锁,用于事务和其他事务查询,不允许事务以共享模式锁定表或更新表中的记录。一般用于select update for语句。

5、exclusive:排他锁,该事务以独占方式写一个表,其他用户只能读取数据。

lock table

lock table允许用户使用一个特定的锁定模式锁定整个数据表。语法:“locak table 数据表列表 in 锁定模式 mode [nowait];”。

如果要解除lock table对表的锁定,只需要简单的使用commitrollbacklock table可以对视图进行锁定,实际上就是对组成视图的基础表进行锁定。

记录锁定

又称行锁定。对当前操作的行锁定,锁定总是以独占的方式进行,在当前事务结束之前,其他事务要等待该事务结束。这种锁称为互斥锁或排他锁。


如果你喜欢我的内容,就请打赏一下吧
微信
支付宝
温馨提示: 你的打赏金额会直接转入对方账户,不可退回。

评论专区


审核通过的评论(0)
暂无评论信息
个人名片

  欢迎来到“浩瀚星尘”的个人博客!
  首先,该博客用于分享本人的生活事迹与兴趣爱好; 此外,该博客的主要作用便是与广大的小伙伴一起分享探讨开发技术, 希望大家多多关照。

网名: 浩瀚星尘
城市: 重庆
工作: java