该项目记录了Oracle相关的速查知识汇总,主要涉及了oracle基础使用、SQL基础、oracle函数、oracle触发器、oracle高级查询、PL/SQL编程基础、PL/SQL存储过程等。若有新增,还将不断添加中。
(7)设置某字段的默认值
在创建表以后添加默认值:
只能以行为单位来删除数据
约束的作用是定义规则(最重要
),确保完整性。
在创建表时设置非空约束:
在修改表时添加非空约束:
在修改表时去除非空约束:
必不可少,确定每一行数据的唯一性。
一张表只能设计一个主键约束。
主键约束可以由多个字段构成,称为联合主键或者复合主键。
在创建表时设置主键约束:
如果没有用约束来创建主键,则系统会自动命名约束的名称,可以看这个:
在修改表时添加主键约束:
更改约束的名称,可以修改任何约束的名字
drop primary key[cascade]; --删除主键约束,如果存在外键约束,填写cascade,可以把其他表中引用该主键约束的一起删掉
两个表之中字段关系的约束。
在创建表的时候设置外键约束:
--table2为主表,table1为从表,也叫主从表。主表当中的字段必须是主表中的主键字段,主从表的字段要设置成同一个数据类型。在向设置了外键约束的表输入值的时候,从表中外键字段的值必须来自主表中的相应字段的值,或者为null值。
如果这样给从表插入数据:
则2在主表中没有找到,会报错。需要填写
才可以,或者那个部分留空值:
在创建表的时候设置外键约束:
--定义完所有的字段之后设置的约束
--后面的中括号是级联删除,表示主表当中的一条数据被删除的时候,从表当中使用了这条数据的字段所在的行也会被一起删除掉,这样确保了主从表数据的完整性。
在修改表时添加外键约束:
作用是保证字段的唯一性,和主键约束的区别是,主键约束必须是非空的,而唯一约束允许有一个空值。主键约束在一张表中只能有一个,唯一约束可以有多个。
在创建表时设置唯一约束:
在修改表时添加唯一约束:
检查约束,让表当中的值更具有实际意义,能够满足一定的条件,具有实际意义。
在创建表时设置检查约束:
在修改表时添加检查约束:
- 主键约束:每张表只能有一个,可以由多个字段构成
- 外键约束:涉及两个表之间的关系
在创建表时设置约束: 只有非空约束只能在列级设置约束,不能在表级设置约束,其他的都是两者都可以的。非空约束是没有名字的。
在修改表时添加约束,也是只有非空约束不同,修改表时用的语句是
更改约束的名称:数据字典(user_constraints查看名称)
删除约束,非空约束较特殊
其他的如果是禁用的话使用
--column可以简写成col,设置新的字段名(别名),使用select语句来查询的时候就可以看到变化了,但使用desc看结构还依然不变化。
注意:字符类型只能设置它的长度。 --字符格式用a开头,后面跟它要的长度。 如
如果是数值类型用,9表示一位数字,比如
可以保留4位数和一位小数。 如果
但如果数据中有四位的数,超过这个长度的就用#####表示了,与excel一致。
清除之前设置过的格式:
(3)查询表中的所有字段
不会更改字段的名字,可以为多个字段设置别名
运算符大家都比较熟悉了,而表达式=操作数+运算符组成。
oracle中的操作数可以有变量、常量、字段。
运算符有算术运算符(+、-、*、/),比较运算符(>,>=,<,<=,=,<>都是用在where条件里面的,两个数进行比较得到的结果是布尔类型的,真或者假),逻辑运算符(and,or,not)
在select语句中使用运算符
在查询结果中,给每个员工的工资加上200元,但数据本身没变。 如
查询工资高于800元的员工的姓名; 如
逻辑运算符的优先级顺序:not,and,or
比较运算符优先级高于逻辑运算符
like关键字,也可以归入比较运算符当中。
通配符的使用(_表示一个字符,%表示0到多个任意字符) 如
between...and --表示从什么到什么之间。查询结果是含头又含尾的区间。
如果不在这个之间的,在它们前面加上not 如
in/not in 后面跟着小括号,里面是一个列表的值,一个具体的值。 如
10.其他一些实用命令
substr(char,[m[,n]]) --获取子字符,分别是从哪取,从哪个位置开始取以及取出多少位,n省略时,从m的位置截取到结束,m从1开始如果m写0也是从第一个字符开始。如果m为负数时,从字符串的尾部开始截取
trim(c2 from c1) --代表从c1中去除c2字符串,就是子文本替换,要求c2中只能是一个字符
ltrim(c1[,c2]) --从c1中去除c2,从左边开始去除,要求第一个就是要去除的字符,有多少个重复的该字符就会去除多少次
rtrim(c1[,c2]) --从c1中去除c2,要求右侧第一个就是要去除的字符,有多少个重复的该字符就会去除多少次
trim(c1) --代表去除首尾的空格,删首尾空,同理ltrim和rtrim只有一个参数时。
add_months(date,i) --用于添加指定的月份,返回在指定的日期上添加的月份,i可以是任意整数,如果i是负数,则是在原有的值上减去该月份了
next_day(date,char) --第二个参数指定星期几,在中文环境下输入星期X即可,返回下一个周几是哪一天。
用于截取日期时间的trunc函数
用法:trunc(字段名,精度)
1、截取时间到年时,sql语句如下:
2、截取时间到月时,sql语句:
3、截取时间到日时,sql语句:
4、截取时间到小时时,sql语句:
5、截取时间到分钟时,sql语句:
6、截取时间到秒暂时不知道怎么操作
8.如果不填写第二个参数,则默认到DD,包含年月日,不包含时分秒。
to_char(date[,fmt[,params]]) --date为需要转换的日期,fmt为转换的格式,params为转换的语言(通常默认会自动选择,可以省略,与安装语言一致)
- 9:显示数字并忽略前面的0
- 0:显示数字,位数不足,用0补齐
- S:加正负号(前后都可以) 如
fmt是转换的格式,可以省略 如
- 将员工信息表中的年龄字段与10取余数
- 查询出5月份入职的员工信息
本部分需要有如下两个部分的基础
- 《oracle数据库开发必备利器之SQL基础》
- 《oracle数据库开发利器之函数》
分组函数作用于一组数据,并对一组数据返回一个值。 结构:
- 求出员工的平均工资和工资的总和
- 求出员工工资的最大值和最小值
二和三结果一样,一不一样,因为在奖金列里面含有空值,count的时候数数不一样
所以分组函数会自动忽略空值,可以在分组函数中使用nvl函数来使分组函数无法忽略空值 如
- 求出员工表中各个部门的平均工资 注意:在select列表中所有未包含在组函数(就是汇总计算xxx的列)中的列都应该包含在group by子句中,但包含在group by子句中的列不必包含在select列表中 如
要求所用包含于select列表中,而未包含于组函数中的列都必须包含于group by子句中。
这里的deptno没有包含在group by子句中,所以会报错。
注意不能在where子句中使用组函数(注意)。
可以在having子句中使用组函数。
如果在能使用where的场景下,从SQL优化的角度来看,尽量使用where效率更高,因为having是在分组的基础上过滤分组的结果,而where是先过滤,再分组。要处理的记录数不同。所以where能使分组记录数大大降低,从而提高效率。
(7)在分组查询中使用order by子句
- 示例:求每个部门的平均工资,要求显示:部门号,部门的平均工资,并且按照工资升序排列 可以按照:列、别名、表达式、序号进行排序
- 按部门、不同的职位显示工资的总额;同时按部门,统计工资总额;统计所有员工的工资总额。 如
rollup就可以实现上述的效果。小计、总计的效果,可以用在报表里面。
再运行上面的代码即可。
部门号 职位 工资总额 部门号 职位 工资总额
按数据库设计原则,员工表中只有部门的编号信息,部门的详细信息会存放在部门表中。
什么是多表查询:就是从多个表中获取数据。
前提是有一个外键约束来表示员工是哪个部门的,有个一个部门号来联结。
有了它才有多表查询的存在。笛卡尔集的列数等于每张表列数的相加,行数等于每张表的行数相乘。比如emp*dept
有六列六行。里面的每一条记录不一定都是对的。多表查询就是要从笛卡尔集中选择出正确的记录。需要一个连接条件,比如部门号相等。有了连接条件,就能避免使用笛卡尔全集。在实际运行环境下,应提供where连接条件,避免使用笛卡尔全集。连接条件至少有要连接表数-1个。
创建笛卡尔集可以使用全连接: FULL JOIN
核心:通过外连接,把对于连接条件不成立的记录,仍然包含在最后的结果中。
左外连接(LEFT [OUTER] JOIN
):当连接条件不成立的时候,等号左边的表仍然被包含
右外连接(RIGHT [OUTER] JOIN
):当连接条件不成立的时候,等号右边的表仍然被包含
改为右外连接 方法是在相反的方向的等值连接结尾加上(+),比如右外连接就是加在左边的最后。
- 作用:通过别名,将同一张表视为多张表(核心)
INNER JOIN
尽管是查询一张表,但本质上仍然是多表查询,会产生笛卡尔集。
可以通过这个看笛卡尔集有多少条记录select count(*) from emp e,emp b;
表越多,次方越多。比如员工表中有一亿条记录,如果看成三张表,就有一亿的立方的笛卡尔集,所以自连接不适合查询大表。
为什么要学习子查询:子查询可以解决不能一步求解的问题
子查询的语法:其实也就是select语句的嵌套
(2)子查询注意的十个问题
语法中一定要有小括号,不然是错的。
该换行的换行,该缩进的索引,可以便于阅读。
select后面使用,要求一定要只返回一条记录,要是单行子查询才行,多行子查询不行。 如
非常的重要,很多问题都是在from后面方式子查询来解决的 如
哪种查询方式好呢?从理论上来讲,尽量使用多表查询比较好,因为子查询需要对数据库访问两次,而多表查询只需要对数据库访问一次。但实际情况下有可能不一样,因为多表查询的笛卡尔集可能很大所以慢了。
- 一般不在子查询中,使用排序;但在Top-N分析问题中,必须对子查询排序
比如找到员工表中工资最高的前三名。
rownum
行号,是一个伪列,表上没有这一列,当做一些特殊操作的时候,oracle自动加上。行号需要注意的问题:行号永远按照默认的顺序生成;行号只能使用<,<=,不能使用>或者>=这样的符号。 如
相关子查询的表必须设定一个别名,然后把主查询的内容传入到子查询中进行查询。 如
这里就把主查询e表中的部门号传入子查询中进行查询了。
- 单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
非法使用单行子查询: 如
group by deptno); --因为子查询返回了不止一行,所以是非法使用单行子查询。
多行操作符:in(等于列表中的任意一个)、any(和子查询返回的任意一个值比较)、all(和子查询返回的所有值比较)
单行子查询中返回空值,要使用in之类的关键字,等于号的话永远为空。
多行子查询中,如查询不是老板的员工 如:
- 分页查询显示员工信息:显示员工号,姓名,月薪
- 注意:rownum只能使用<,<=不能使用>,>=,因为oracle数据库是一个行式数据库,取了第一行才能取第二行,所以行号永远从1开始,所以比如rownum>=5这样的条件永远为假。
如果需要查询执行计划看性能的话,则在语句前面加上EXPLAIN PLAN FOR
- 按部门统计员工人数,按照规定格式输入,已知员工的入职年份在80,81,82,87年之中。 如
新建两个表,然后按要求查到相关的内容
1.需要进行两个表的连接查询,为两个表都取别名
2.使用instr(a,b)函数,该函数的含义为:如果字符串b在字符串a的里面,则返回的是b在a中的位置,及返回值大于0
1 张三,赵六,王五,李四
同时学会了一个,如果在oracle中,需要实现如果表已经存在则先删除表的操作,写法为:
其中查询的表名和drop的表名变成你要检测的表名即可。
使用PLSQL语言操作Oracle数据库的效率最高。
之前用sql语句是命令式的语言,但如果案例是复杂的,比如需要分条件来做不同的事情的,就需要PL/SQL效率会更高,不需要用其他的编程语言。
指在SQL命令语言中增加了过程处理语句(如分支、循环等),使SQL语言具有过程处理能力。
(1)是sql的扩展,支持sql语句。
(2)是面向过程的语言。
--说明部分(变量说明、光标申明、例外说明) --程序体(DML语句)
/ --这个正斜杠用来退出前面的代码编写并且执行语句
4.不同数据库中SQL扩展
举例:名字在片面,变量是在后面,:=为赋值符号不是单=号
这里的into就可以赋值,是一一对应的。
--取表中一行的类型,作为变量的类型,可以理解为数组,如果需要取用到列里面的某一行,就像如下写法:
select如果返回的结果有多行的话就会出错,所以需要引入光标,光标cursor就是一个结果集。也叫游标。
此外,光标是可以带参数的。
(1)把当前指针指向的记录返回;
(2)将指针指向下一条记录。
- %isopen:判断光标是否打开
- %rowcount:影响的行数,不是总行数,比如光标取走了10行的数据,那么这个值就是10
默认情况下,oracle数据库只允许在同一个会话中打开300个光标
scope是范围,取值有三个:both, memory(只更改当前实例), spfile(只更改参数文件,数据库需要重启)
例外是程序设计语言提供的一种功能,用来增强程序的健壮性和容错性。
- timeout_on_resource 在等待资源时发生超时(分布式数据库的访问会用到)
使用raise关键字抛出自定义例外
设计1.概要设计2.详细设计
以上步骤就像水流一下,最忌讳一上来就编码。
想明白SQL语句、变量。
变量:1.初始值是多少2.最终值如何得到
- 使用||符号来连接文本字符串。
- --表示单行注释,/* */表示多行输入
- plsql中大小写不敏感。
- then语句相当于一个大括号,后面的语句可以一起被处理,比如如下写法:
这里两句话都会被打印出来。
- 把握一个原则:能不操作数据库就不操作数据库,比单单加减乘除的计算慢。
触发器是一个特殊的存储过程。是一个与表相关联的、存储的PL/SQL程序。
作用:每当一个特定的数据操作语句(insert、update、delete,注意没有select)在指定的表上发出时,oracle自动地执行触发器中定义的语句序列。
在指定的操作语句操作之前或之后执行一次,不管这条语句影响了多少行。
语句级触发器针对表,只会触发一次
触发语句作用的每一条记录都被触发。在行级触发器中使用:old和:new伪记录变量,识别值的状态。如果有for each row就表示行级触发器。 如
行级触发器针对行,有多少条记录就触发多少次。
每当成功插入新员工后,自动打印一句话,"成功插入新员工"。单词trigger
4.触发器的具体应用场景
(1)复杂的安全性检查 --比如周末不允许操作数据库
(2)数据的确认 --涨后的工资大于涨前的工资
(3)数据库审计 --跟踪表上所做的数据操作,什么时间什么人操作了什么数据,操作的人是什么。基于值的审计
(4)数据的备份和同步 --异地备份,把主数据的数据自动同步到备数据库中
- 触发器案例一:禁止在非工作时间插入数据
- 触发器案例二:涨工资不能越涨越少
:old
和:new
的使用要注意。
- 触发器案例三:创建基于值的触发器
PLSQL子程序体; (关键字可以小写)(如果不传参,则参数列表的小括号也可以省略)
这个PLSQL子程序体;一般为:
如果写的是存储函数,那么这里的PROCEDURE需要改成FUNCTION,而且必须在参数列表和AS之间添加一句:RETURN 函数值类型
。而且需要在子程序体需要返回的时候写return 返回值
。
写好之后先编译,然后调用、运行。
as后面跟的是说明部分,相当于declare。
在参数列表中,如果是输入参数,可以写入eno in number,in是关键,in前面是变量名,后面是变量类型。
如果是输出参数,写eno out number,out是关键,out前面是变量名,后面是变量类型。
存储过程和存储函数都可以有out参数。
他们都可以有多个out参数。
存储过程可以通过out参数来实现返回值。
查询某个员工姓名、月薪和职位
--得到该员工的姓名、月薪和职位
5.在out参数中使用光标案例
案例:查询某个部门中所有员工的所有信息。
包头(负责声明包中的结构):
注意:包头中也可以不定义存储过程,只定义光标那一行。
包体(负责写需要实现包头中声明的所有方法):
--打开光标类型(是一个集合,意味着可以返回许多信息的集合)
注意:包体里面的存储过程也可以不写在包体内部也可以一样调用包头中定义的光标。
- 参数列表可以换行,也可以在关键字之间多加空格。
- 如果是没有参数的就是存储过程,如果有参数就是存储函数。存储函数可以有一个返回值,可以用return子句进行返回。
- 我们的原则是,如果只需要一个返回值,则用存储函数。如果没有返回值,用存储过程,如果需要有多个返回值,则使用存储过程,在参数中使用out参数。
- 单行注释使用“--注释内容”,多行注释使用“/* 注释内容 */”。
哪个权限没有就到sqlplus输入如下代码:
grant 要调的权限(中间用逗号分隔) to 用户名;
一些不知道插进过去的哪些笔记的笔记就放在这里吧~
为例, exists表示,对于A中的每一个记录,如果,在表B中有记录,其属性a的值与表A这个记录的属性a的值相同,则表A的这个记录是符合条件的记录,
如果是NOT exists,则表示如果表B中没有记录能与表A这个记录连接,则表A的这个记录是符合条件的记录。