一、简单查询
1.查询数据库表所有的列
Select * from 表名;
Select 列名,列名… from 表名;
2.起别名
Select 列名 [as 别名],列名 别名… from 表名;
–正常情况
Select ename as 员工姓名,sal salary from emp;
–别名正好是关键字,别名需要用””括起来
Select ename as “select”,sal “from” from emp;
–别名的中间存在空格,别名需要用””括起来
Select ename as “select”,sal “employee sal” from emp;
3.distinct:去重
–查询emp表中不同的职务
Select distinct job from emp;
–查询emp表中每个部门不同的职务
–查询emp表中不同部门不同的职务
Select distinct depot,job from emp;
Select distinct depot, distinct job from emp;错误
注意:select 后面,多列去重,在所有的列前面只写一个distinct
4.||管道符号:用来连接输出 通常用于格式输出
–将每个员工的信息输出为如下格式
姓名为。。。,工资为。。。。
字符串和日期都是用’’引起来
Select ‘姓名为:’||ename|| ‘工资为:’||sal from emp
5.四则运算
–查询员工的姓名和年薪
Select ename, sal*12 年薪 from emp;
Select ename, (sal+nvl(comm,0)*12 年薪 from emp;
当与null值参与运算或者比较时,结果一定为null值
nvl(a1,a2):判断a1是否为null,如果不为null,结果为a1,为null,结果为a2.
练习:
• 1.员工转正后,月薪上调20%,请查询出所有员工转正后的月薪。
• SELECT ename 员工姓名,sal*1.2 转正后薪资 FROM emp
• 2.员工试用期6个月,转正后月薪上调20%,请查询出所有员工工作第一年的年薪所得(不考虑奖金部分,年薪的试用期6个月的月薪+转正后6个月的月薪)
• SELECT ename 员工姓名,sal*6+sal*1.2*6 工作一年的薪资 FROM emp
• 3.员工试用期6个月,转正后月薪上调20%,请查询出所有员工工作第一年的所有收入(需考虑奖金部分),要求显示列标题为员工姓名,工资收入,奖金收入,总收入。SELECT ename 员工姓名,sal*6+sal*1.2*6 工资收入,NVL(comm,0)*12 奖金,sal*6+sal*1.2*6+NVL(comm,0)*12 总收入 FROM emp
• 4.员工试用期6个月,转正后月薪上调20%,请查询出所有员工工作第一年的所有收入(需考虑奖金部分),要求显示格式为:XXX的第一年总收入为XXX。
• SELECT ename || ‘的第一年总收入为:’ || (sal*6+sal*1.2*6+NVL(comm,0)*12) FROM emp
二、排序
Select 列名 [as 别名],列名 别名… from 表名;
Order by 排序字段 asc|desc,排序字段 asc|desc…;
排序字段,可以是列名,列的别名,列的顺序号,函数结果
–select * from emp order by deptno,sal desc;
– select ename a,deptno b,sal c
From emp
Order by b,c desc;
Order by 2,3desc;
–按照员工部门编号升序排序,部门相同按照奖金降序排序
Select ename a,deptno b,sal c comm form emp order by 2,nvl(comm,0) desc
三、限定查询
Select 列名 [as 别名],列名 别名… from 表名
Where 条件
Order by 排序字段 asc|desc,排序字段 asc|desc…;
1.关系运算符:> < + = ….
可以比较数据类型:数值、字符串、日期
–查询员工工资大于2500的员工信息
Select * from emp where sal>2500
–查询在1982年之后入职的
‘DD-MM-RR’ 格式注意
SELECT * from emp where hiredate > ‘31-12月-1982’;
2.逻辑运算符
And:与
Or:或
Not:非
Not>and>or
–员工的职务是manager或是salesman,且工资大于1500的员工姓名
Select ename,job,sal from emp where
(job=’manager’or job=’salesman’)and sal>1500
3.between….and….闭区间
语法:字段名[not] between 最小值 and 最大值
–查询在1982年入职的员工
4.in:集合运算
语法格式:字段名[not] in(值1,值2,……..)
– Select ename,job,sal from emp where
Job in (’manager’,’salesman’)and sal>1500
5.is null:没有
Is not null:有
–查询没有领导的员工信息
Select * from emp where mgr is null
–查询奖金不为null的员工信息
Select * from emp where comm is not null
6.like:模糊查询
语法:字段名 [not] Like ‘匹配字符串’ [escape ‘转义字符’]
_:任意一个字符
%:0个或多个任意字段
- -查询员工信息包含%的员工信息
Select * from emp where ename like ‘%%%’ escape’’;
此处的第二个%为转义后的。一般不以字母为转义符
练习:1.查询入职时间在1982-7-9之后,并且不从事SALESMAN工作的员工姓名、入职时间、职位。SELECT ename,hiredate,job
FROM emp
WHERE hiredate>’9-7月-1982’AND job <>’SALESMAN’
2.查询员工姓名的第三个字母是a的员工姓名。
SELECT ename
FROM emp
WHERE ename LIKE ‘__a%’
3.查询除了10、20号部门以外的员工姓名、部门编号。
SELECT ename,deptno
FROM emp
WHERE deptno NOT IN(10,20)
4.查询部门号为30号员工的信息,先按工资降序排序,再按姓名升序排序。
SELECT *
FROM emp
WHERE deptno=30
ORDER BY sal DESC,ename ASC
5.查询没有上级的员工(经理号为空)的员工姓名。
SELECT * FROM emp WHERE mgr IS NULL
6.查询工资大于等于4500并且部门为10或者20的员工的姓名\工资、部门编号。
SELECT ename,sal,deptno
FROM emp
WHERE sal>4500 AND deptno IN (10,20)
四、单行函数
字符函数、数值函数、日期函数、转换函数、通用函数
字符函数
1.Upper()转大写
2. Lower()转小写
3. Initcap()转首字符大写,其他字符小写
4. Length()长度
SELECT UPPER(ename),LOWER(ename),INITCAP(ename),LENGTH(ename) FROM emp
Dual :只有一个字段,sys用户的一张表,sys创建了该表的公共同义词
5. Trim():去掉首尾的空格, SELECT TRIM(’ ddddd ‘) FROM dual;
Trim(‘h’ from ‘test’)去掉test首尾的h
SELECT TRIM(‘d’ FROM ‘dlldddd’) FROM dual
6.concat(s1,s2)连接字符串=双管道||
Select concat(ename,job) from emp
7.instr(str1,str2):返回str2在st1中的位置SELECT INSTR(‘hello’,’l’) FROM dual instr(str1,str2,[n,n2]) 返回str2在st1中的位置,从n1位置开始,查找第n2次出现的位置,没有就返回0
8.replace(s1,s2,s3)将s1中的s2用s3代替
9.substr(str,loc,length):截取子串tr从str的loc开始截取,截取长度为length
首尾截取,为0或1:Select substr(‘hello’,0,3) from dual
截取到尾部省略,第三个参数:Select substr(‘hello’,2) from dual
截取中间子串:Select substr(‘hello’,2,2) from dual
10. lpad(s1,length,s2)判断s1的长度是否等于length,如不等,在左边补s2,直到长度为length为止
11.rpad(s1,length,s2) 判断s1的长度是否等于length,如不等,在左边补s2,直到长度为length为止
select lpad(‘hello’,10,’#’) from dual
如果字符串长度大于10,截取10位,严格控制长度大小
练习:
• 1.写一个查询,用首字母大写,其它字母小写显示雇员的 ename,显示名字的长度,并给每列一个适当的标签,条件是满足所有雇员名字的开始字母是J、A 或 M 的雇员,并对查询结果按雇员的ename升序排序。(提示:使用initcap、length、substr)
SELECT INITCAP(ename),LENGTH(ename)
FROM emp
WHERE SUBSTR(ename,1,1) IN (‘J’,’A’,’M’)
ORDER BY ENAME
• 1.查询员工姓名中中包含大写或小写字母A的员工姓名。
SELECT ename
FROM emp
WHERE UPPER(ENAME) LIKE ‘%A%’
–查询工作为cleck的员工姓名
SELECT ename
FROM emp
WHERE lower(job) =’cleck’
• 2.查询部门编号为10或20,入职日期在81年5月1日之后,并且姓名中包含大写字母A的员工姓名,员工姓名长度(提示,要求使用INSTR函数,不能使用like进行判断)
• SELECT ename,LENGTH(ename)
• FROM emp
• WHERE deptno IN (10,20) AND hiredate>’1-5月-1981’AND instr(ename,’A’)>0
• 3.查询每个职工的编号,姓名,工资
– 要求将查询到的数据按照一定的格式合并成一个字符串.
– 前10位:编号,不足部分用*填充,左对齐
– 中间10位:姓名,不足部分用*填充,左对齐
– 后10位:工资,不足部分用*填充,右对齐
SELECT RPAD(empno,10,’‘)||RPAD(ename,10,’‘)||LPAD(ename,10,’*’) FROM emp
数值函数
1.round(num,p):四舍五入
P=0:四舍五入为整数
P>0:四舍五入到小数点右边第p位
P<0:小数点左边第|p|位四舍五入
1. Trunk(num,p):截断
P=0: 截断为整数
P>0: 截断小数点右边第p位
P<0:小数点左边第|p|位截断
2. mod(n1,n2):n1对n2求余
日期函数
规则:日期-日期=天数
日期+天数=日期
当前系统日期:sysdate DD-MON-RR(默认格式)
1. month_between(date1,date2);返回两个日期之间相差的月份
如果date1>date2,返回正数
–统计每个人入职多少月
SELECT ename,trunc(months_between(SYSDATE,hiredate)) FROM emp
–统计每个人入职多少年零多少月零多少天
2. next_day(date,weekday):返回指定日期的下个星期几是什么日期
SELECT next_day(SYSDATE,’星期一’) FROM dual
- last_day():返回指定日期所在月份的最后一天。
select last_day(sysdate) from dual - add_months(date,month):在指定日期上增加若干个月后的日期
select add_months(sysdate,4) from dual - extract([month day year] from date):从指定日期中取出日期中的年、月、日
SELECT EXTRACT(YEAR FROM SYSDATE) FROM dual
–查询1982年入职的员工信息
SELECT *
FROM emp
WHERE EXTRACT(YEAR FROM hiredate)=1982
6.(了解)
Round(date,fmt)
Select round(sysdate,’MM’) from dual
Trunk(date,fmt)
Fmt:
CC:世纪
YY:年
MM:月
DD:天
HH:时
MI:分
SS:秒
转换函数 to_char():转换为字符串
1.1将日期转换为字符串:to_char(date,’format’)转换为固定格式的字符串
yyyy:年
mm:月
dd:日
day:星期
hh时
mi分
ss秒
mon月
SELECT to_char(SYSDATE,’yyyy-mm-dd hh24:mi:ss day’) FROM dual
2018-07-09 15:32:56 星期一
SELECT *
FROM emp
WHERE to_char(hiredate,’yyyy’)=1982
1.2将数值转换为字符串(将数值转换为指定格式的字符串)
常见的格式:
.:代表小数点
9:代表任意数字
,:千位符
L:本地货币符号
$:美元
SELECT to_char(4555.55,’L999,999.99’)
FROM dual
结果:¥4,555.55to_number(str,’format’):将固定格式的字符串转换为数值
SELECT to_number (¥4,555.55,’L999,999.99’)
FROM dual
结果:4555.55- to_date(str,’format’):转为日期,将固定格式的字符串转换为日期
SELECT to_date(‘21-12-2018’,’dd-mm-yyyy’)
FROM dual
结果:2018/12/21 星期五
练习:
• 1.显示服务器系统当前时间,格式为2007-10-12 17:11:11(提示:使用to_char函数)
• SELECT to_char(SYSDATE,’yyyy-mm-dd hh24:mi:ss’)
• FROM dual 结果:2018-07-09 15:51:32
• 2.显示ename、hiredate 和 雇员开始工作日是星期几,列标签DAY(提示:使用to_char函数)
• SELECT ename,hiredate,to_char(hiredate,’day’) DAY
• FROM emp
• 3.查询员工姓名,工资,格式化的工资(¥999,999.99) (提示:使用to_char函数)
• SELECT ename,sal,to_char(sal,’L999,999.99’)
• FROM emp
• 4.把字符串2015-3月-18 13:13:13 转换成日期格式,并计算和系统当前时间间隔多少天。 (提示:使用to_date函数)
SELECT TO_date(‘2015-3月-18 13:13:13’,’yyyy-mon-dd hh24:mi:ss’),EXTRACT(DAY FROM SYSDATE) DAY FROM dual
SELECT months_between(SYSDATE,TO_date(‘2015-3月-18 13:13:13’,’yyyy-mon-dd hh24:mi:ss’)) FROM dual
通用函数
1. nvl():
2. nvl2(arg1,arg2,arg3):判断arg1是否为null,如果不为null,返回arg2,否则返回arg3
select ename,comm,nvl2(comm,comm,0) from emp;
3. decode():类似于等值的判定语句,类似于switch语句
语法:decode(exp/comm,值1,结果1,值2,结果2….,值n,结果n,结果m);
—判定员工姓名中含A或a的位置,如果位置在首位,显示“A在首位”,如果位置在末尾,显示“A在末尾”,如果A在中间,显示”A在中间”,否则,“不包含A”
SELECT ename,decode(instr(upper(ename),’A’),1,’A在首位’,0,’不包含A’,LENGTH(ename),’A在末尾’,’A在中间’)
FROM emp;
4. case():
格式一:
case when 条件1 then 结果1
case when 条件2 then 结果2
……….
case when 条件n then 结果n
else 结果m
end;
SELECT ename,CASE WHEN upper(ename) LIKE ‘A%’ THEN ‘A在首位’
WHEN upper(ename) LIKE ‘%A’ THEN ‘A在末尾’
WHEN upper(ename) NOT LIKE ‘%A%’ THEN ‘不包含A’
ELSE ‘A在中间’
END
FROM emp;
格式二:
Case 表达式/列名 when 值1 then 结果1
………..
when 值n then 结果n
else 结果m
end
五、多表查询
select 列名,列名…..
From 表名 表的别名,表名 表的别名….
Where 条件
Order by 排序字段
1. 笛卡尔积:是多张表记录的乘积 Select * from emp,dept;
条件连接,规避笛卡尔积的出现
2. 等值连接:两张表中存在含义相同,值相等的列。
Select ename,d.deptno,dname
From emp e, dept d 注意:表有别名后,别名生效,原名就无效了
Where e.deptno=d.deptno
- 不等值连接
Select * from salgrade;
Select * from emp e,salgrade s
Where e.sal>=s.losal and e.sal<=s.hisal
–查看员工的姓名,部门名称,工资的等级
Select *
From emp e,dept d,salgrade s
Where e.deptno=d.deptno and e.sal between loser and hisal - 自身连接
Select * from emp a,emp b
Where a.mgr=b.empno - 外连接:
外部连接就好象是为符号(+)所在边的表增加一个“万能”的行,这个行全部由空值组成。
查询所有雇员姓名,部门编号,部门名称,包括没有员工的部门也要显示出来
SELECT e.ename, d.deptno, d.dname
FROM emp e, dept d
WHERE e.deptno(+) = d.deptno
ORDER BY e.deptno; - SQL1999;
6.1 cross join :交叉连接,笛卡尔积
语法:table cross join table1
Select * from emp cross join dept
6.2 natural join :自然连接
语法:table1 natural join table2
Select * from emp natural join dept
6.3 join…using(公共列)
语法:table join table1 using(公共列)
Select * from emp join dept using(deptno)
6.4 join…on 连接条件
语法:tabe1 join table2 on 连接条件
Select * from emp join dept on emp.deptno=dept.deptno
6.5 left join…on 连接条件 左边表全部实现,右边不足补充
语法:table1 left join table2 on 连接条件
6.6 right join…on 连接条件 右边表全部实现,左边不足补充
语法:table1 right join table2 on 连接条件
6.7 full join…on 连接条件 全外连接
语法:table1 full join table2 on 连接条件
两个表的所有信息都会显示
练习: - 显示员工SMITH的姓名,部门名称,直接上级名称
SELECT e.ename,d.dname,m.ename
FROM emp e,dept d,emp m
WHERE e.ename=’SMITH’ AND d.deptno=e.deptno AND e.mgr=m.empno 显示员工姓名,部门名称,工资,工资级别,要求工资级别大于4级。
SELECT e.ename,d.dname,e.sal,s.grade
FROM emp e,dept d,salgrade s
WHERE d.deptno=e.deptno AND e.sal BETWEEN losal AND hisal显示员工KING和FORD管理的员工姓名及其经理姓名。
SELECT e.ename,m.ename
FROM emp e,emp m
WHERE e.mgr=m.empno AND m.ename IN(‘KING’,’FORD’)- 显示员工姓名,参加工作时间,经理名,参加工作时间,要求参加时间比经理早。
SELECT e.ename,e.hiredate,m.ename,m.hiredate
FROM emp e,emp m
WHERE e.mgr=m.empno AND e.hiredate < m.hiredate
六、分组查询
1.分组函数:又叫统计函数,聚合函数 查询时不能加列,只能加处理的列
Sum():求和
Avg():求平均
Max():求最大值
Min():求最小值
count():求个数 一般统计主键列
*统计表的记录数
列名:统计该列不为null 的个数
注意:统计时,不对null值进行处理
2.select
From
Where
Group by 分组字段,分组字段。。。有去重作用
Having 组过滤条件
Order by
执行顺序:from—where—group by—having—select—order by
–统计不同的领导的工号个数
Select count(distinct mgr) from emp;
Select count(mgr ) from emp group by mgr 统计每组经理的个数
–统计各个部门不同职务的薪资总和,平均工资,部门名称,职务
Select dname, dept.deptno ,job,sum(sal),avg(sal)
From emp,dept
Where emp.deptno=dept.deptno
Group by dname,dept.deptno,job
Order by dname
–查询各个部门平均工资大于2000的部门编号和平均工资
Select deptno,avg(sal)
From emp
Group by deptno
Having avg(sal)>2000
Where:在分组前进行过滤。Where 的后面不能直接使用分组函数做比较
Having:分组后进行过滤。
3.分组函数的嵌套
当select后面的分组函数嵌套使用时,select后面不能有任何列名,只能存在嵌套分组函数
七、子查询
子查询一般用()括起来
出现的位置:select, from, where, having
嵌套子查询:一个查询语句中嵌套另外一个查询语句,子查询的语句可以直接运行
三类:1.单列子查询:子查询的返回结果是单行单列的,经常用在where, having
2.多行子查询:子查询的返回结果是单列多行的,经常用在where
3.多列子查询: 子查询的返回结果是多行多列的,经常用在from, where
1.单行子查询
–查询工作和smith一样的其他员工信息
Select *
from emp
Where job=(select job from emp where lower(ename)=’smith’)AND lower(ename)!=’smith’
2.多行子查询
集合运算:in
SELECT *
FROM emp
WHERE job IN(SELECT DISTINCT job FROM emp WHERE deptno=30)
any
=any:相当于in
SELECT *
FROM emp
WHERE job =ANY(SELECT DISTINCT job FROM emp WHERE deptno=30)
any:比子查询返回结果的最小值要大
–比10部门额最低工资要高额其他部门的员工信息
SELECT *
FROM emp
WHERE sal>ANY(SELECT sal
FROM emp
WHERE deptno=10) AND deptno!=10
CONNECT BY PRIOR 条件
LEVEL:节点的层次,伪列,由查询的起点开始算起为1,依次类推。
FROM table:指定表、视图或包含列的快照,你只能从单独的一个表中选择。
WHERE: 限制返回的行。
Condition:是一个比较式。
START WITH:指定层次的根行 (起点)。这个子句对于一个正确的分级查询是必须的。
CONNECT BY PRIOR:指定存在父与子行的关系列。对于分级查询该子句是必须的。
从顶向下查询:CONNECT BY PRIOR 父=子
SELECT level,empno,ename,mgr,sal
FROM emp
START WITH empno=7698
CONNECT BY PRIOR mgr=empno
从底向上查询:CONNECT BY PRIOR 子=父
SELECT level,empno,ename,mgr,sal
FROM emp
START WITH empno=7698
CONNECT BY PRIOR empno=mgr
SELECT * FROM emp
十二、数据库网络连接
1.基本配置
地址,实例名、监听,账号,密码
1、创建数据库实例或删除实例,修改实例
配置移置工具—》database configuration assistant 相当于执行oracle安装目录下bin目录中的dbca.bat
一个数据库实例包含三类文件:数据文件(.dbf)、控制文件(.ctl)、日志文件(.log)
2、配置监听
配置移置工具—》net configuration assistant 相当于执行Oralce安装目录bin目录中的netca.bat
3、连接数据库:
连接数据库,全连接
方法1.sqlplus 用户名/密码@数据库服务器IP:监听端口/实例名
例如(本机的): sqlplus scott/[email protected]:1521/orcl
方法2:sqlplus 用户名/密码@本地服务名— sqlplus scott/123@ orcl
sqlplus 用户名/密码 —连接的是默认数据库,如果有多个实例存在,将不清楚自己连接的到底是哪一个实例
sqlplus登录数据库成功后,切换用户 ,如何切换
以sys身份访问,直接以用户身份访问
sqlplus /@数据库服务器IP:监听端口/实例名 as sysdba; — sqlplus /@orcl as sysdba 以sys访问
切换1:conn 用户名/密码@数据库服务器IP:监听端口/实例名
切换2:conn 用户名/密码@本地服务名
conn /@数据库服务器IP:监听端口/实例名 as sysdba;
2.连接外端数据库
步骤1:
点击+,添加服务
名字随便起orcl2
10.10.76.204为对方的IP地址值
对方的orcle实例名(登录界面进行选择的服务名)
更改登录,填写对方数据库实例的账号和密码,然后进行登录校验
最后保存一下配置
回到PLSQL,输入库,账号密码即可。若登录失败,可检查一下tools里的preferens.
十三、数据的增删改
1.备份表
1.1全表备份
CREATE TABLE 新表名 AS 子查询
–将emp表全表备份
CREATE TABLE emp_b AS SELECT * FROM emp
1.2只备份表结构,不备份数据
语法:CREATE TABLE 新表名 AS 子查询 WHERE 1=2
CREATE TABLE emp_b1 AS SELECT * FROM emp WHERE 1=2
1.3备份表的时候修改列名
语法:CREATE TABLE 新表名(新列名) AS SELECT 列名,列名。FROM 表名 WHERE 条件
2.新增表数据
2.1复制表数据
–INSERT INTO 表名(列名,列名) 子查询
INSERT INTO emp_b1(empno,ename,job) SELECT * FROM dept
2.2插入数据
INSERT INTO 表名[(列名,列名..)] VALUES (值1,值2…)
DESC 表名:直接输出表结构
SELECT * FROM emp_b1
–DESC emp
注意:当插入数据时,表没有指定列名,如果列中想要插入Null或默认值
值可以不写,要写成null或default
插入数据写列名,对于没有指定的列,如果有默认值直接附默认值,如果没有,直接给null
—使用子查询插入数据
INSERT INTO emp(empno,ename,job,sal,deptno)
VALUES(‘ss’,’ss’,1200,20,(SELECT deptno FROM dept WHERE UPPER(dname)=’SALES’))
3.修改表数据
UPDATE 表名 SET 列名=新值,…[WHERE 条件]
–修改表数据
UPDATE emp SET sal=sal*1.2 WHERE UPPER(job)=’CLERK’
3.2全表修改
UPDATE emp SET sal=sal*1.2
—使用子查询
UPDATE EMP SET sal=sal+500,comm=200 WHERE deptno=(SELECT deptno FROM dept WHERE UPPER(dname)=’SALES’);
4.删除表数据
4.1 删除部分表数据 DELETE [FROM] 表名 [WHERE 条件]
删除全表 : DELETE 表名
4.2 截断表:删除全表数据
TRUNCATE TABLE 表名;
TRUNCATE TABLE emp_b1
DELETE 和 TRUNCATE 区别
1.delete 可以删除部分数据,TRUNCATE只能删除全部数据
2.delete 删除的数据可以回滚,TRUNCATE不允许回滚
3.delete 的删除速度比TRUNCATE慢,因为delete要写日志
5.事务:TPL
DQL:数据查询语言:SELECT
DML:数据操作语言:INSERT DELETE UPDATE
DDL:数据定义语言:CREATE ALTER DROP
DCL:数据控制语言:GRANT REVOKE
TPL: 事务语言:COMMIT ROLLBACK,SAVEPOINT
1. COMMIT :提交
2. ROLLBACK:回滚
3. SAVEPOINT 保存点名,设置事务保存点
4. ROLLBACK TO :事务保存点,回滚至事务保存点
6新增表
创建表
Creat table 表名(
列名 数据类型[default 默认值 约束],
列名 数据类型[default 默认值 约束],
列名 数据类型[default 默认值 约束])
1. 查询表结构: sqlplus命令
Desc 表名:可以查询表结构
2. 数据类型
数值型:number
字符串类型:varchar2
日期型:date
大对象类型:clob,blob
2.1 数值 number(p,s) p代表有效位数,s代表精度
S=0:number(p)
S<0:小数点左边的有效位数为:p+|s|位,小数点左边的第|s|位开始四舍五入
s>0:小数点右边的位数为s,小数点左边的有效位数为p-s位
2.2字符串类型
Char(n):固长字符串,无论字符串的长度是否为N,结果都是N,不足补空格
Varchar2():变长字符串,字符串有几位占用几位
2.3 日期型
默认日期:日-月-年
INSERT INTO A VALUES(‘10-10月-2018’);
insert into a values(to_date(‘20181010’,’yyyymmdd’));
2.4 对象(4G以内)
Clob:文件对象
Blob:二进制对象
7.修改表
1. 添加列
2. 修改列的属性:修改数据类型、长度、默认值、约束
3. 修改列名
4. 删除表
5. 修改表名
1.添加列
ALTER TABLE 表名 ADD(列名 数据类型 [DEFAULT 默认值 约束],列名 数据类型 [DEFAULT 默认值 约束]…);
2.修改列的属性:修改数据类型,长度,默认值,约束
alter table 表名 modify(列名 数据类型 [DEFAULT 默认值 约束]…);
3.修改列名
alter table 表名 rename column 旧的列名 to 新的列名;
4.删除列
alter table 表名 drop column 列名;
5.修改表名
rename 旧的表名 to 新的表名;
8.删除表
drop table 表名 [cascade constraints];
CASCADE CONSTRAINTS:—当主键记录被外键引用时,可以添加此选项删除表的同时删除相关约束.
十四、约束
1.非空约束 not null
不允许为空值
1.1建表时创建非空约束
Create table 表名(
列名 数据类型[default 默认值 约束] not null,(default放在not null前面)
列名 数据类型[default 默认值 约束]
)
1.2修改表时创建非空约束
Alter table 表名 modify(列名 not null)
由 not null 修改为 null
2.主键约束:
又称唯一索引键,不允许主键的值为null且不允许重复
Primary key
2.1建表的时候创建
Create table 表名(
列名 数据类型default 默认值 Primary key,
)
2.2在后面直接创建
Create table 表名(
列名 数据类型default 默认值,
Constraint 约束名 Primary key(约束内容)
)
2.3修改表的时候直接创建
Alter table 表名 add constraint 约束名 Primary key(约束内容)
2.4删除主键约束
Alter table 表名 drop constraint 约束名;
3.唯一约束:
值不允许重复 unique
3.1建表的时候创建
Create table 表名(
列名 数据类型default 默认值 unique,
)
3.2在后面直接创建
Create table 表名(
列名 数据类型default 默认值,
Constraint 约束名 unique (约束内容)
)
3.3修改表的时候直接创建
Alter table 表名 add constraint 约束名 unique (约束内容)
3.4删除唯一约束
Alter table 表名 drop constraint 约束名;
4.检查约束:check
4.1建表的时候创建
Create table 表名(
列名 数据类型default 默认值 check(条件)
)
4.2在后面直接创建
Create table 表名(
列名 数据类型default 默认值,
Constraint 约束名 check(条件)
)
4.3修改表的时候直接创建
Alter table 表名 add constraint 约束名 check (条件)
4.4删除check约束
Alter table 表名 drop constraint 约束名
5.外键约束
foreign key
父表:主键
子表:外键
子表外键的值必须在父表的主键中存在
5.1建表的时候创建
Create table 表名(
列名 数据类型default 默认值 references 父表(主键)
)
5.2在后面直接创建
Create table 表名(
列名 数据类型default 默认值,
Constraint 约束名 foreign key(外键) references 父表(主键)on delete cascade
)
5.3修改表的时候直接创建
Alter table 表名 add constraint 约束名 foreign key(外键) references 父表(主键)on delete cascade
5.4删除check约束
Alter table 表名 drop constraint 约束名
5.5on delete cascade:级联删除 当父表的主键记录删除时,子表的相关记录(所有记录)会一并删除
十五、视图
Create [or replace] view 视图名 as 子查询 [with read only | with check option]
1.创建视图表
Create view view_1 as seect * from emp where deptno=20
对视图表的操作就是间接操作原表。
2.with read only:只读视图
3.with check option:条件检查,满足where条件才能执行相应的视图操作
4.复杂视图:
4.1视图的子查询中包含了distinct,不允许对视图增删改,只能查询
Create or replace view v_emp as select distinc deptno,job from emp;
4.2视图表的子查询中包含rownum,不允许对视图增删改,只能查询
Create or replace view v_emp as select rownum r, deptno,job from emp;
4.3视图的子查询包含了分组函数,不允许对视图增删改,只能查询
Create or replace view v_emp as select count(empno) c,sum(sal) s from emp;
4.4视图的子查询中包含了group by 子句, 不允许对视图删改,允许新增和查询
Create or replace view v_emp as select empno,ename from emp group by empno,ename;
4.5视图的子查询中包含了表达式,不允许对视图表的表达式列进行增加和修改的操作,允许对非表达式的列进行增删改查(sal*1.2属于表达式列)
Create or replace view v_emp as select empno,sal*1.2 sal from emp
4.6视图表中不包含源表中的非空约束列,不允许增加,可以修改删除和查询
5.删除视图
Drop view 视图名;
练习:
1.创建视图v_emp_20,包含20号部门的员工编号,姓名,年薪列(年薪=12*(工资+奖金);
CREATE OR REPLACE VIEW v_emp_20 AS SELECT empno,ename,(sal+NVL(comm,0))*12 年薪 FROM emp
DROP VIEW v_emp_20
2.从视图v_emp_20中查询年薪大于1万元员工的信息;
SELECT * FROM v_emp_20 WHERE 年薪>10000
3.请为工资大于2000的员工创建视图,要求显示员工的部门信息,职位信息,工作地点;
CREATE OR REPLACE VIEW v_emp_1
AS SELECT deptno,job,loc
FROM emp NATURAL JOIN dept
WHERE sal>2000
SELECT * FROM v_emp_1
十六、序列
创建序列
Create sequence 序列名
[INCREMENT BY n] —步长
[START WITH n] –序列的起始值
[MAXVALUE n | NOMAXVALUE] —序列的最小值
[MINVALUE n | NOMINVALUE] –序列的最大值
[CYCLE | NOCYCLE] –序列设置循环取值的标志
[CACHE n | NOCACHE]; —序列的缓存个数
–所有的属性设置为默认值的序列
Create sequence myseq;
–设置属性值为指定值的序列
CREATE SEQUENCE test_seq
START WITH 10 –序列从10开始
INCREMENT BY 2 –序列每次增加2
MAXVALUE 100 –序列最大值100
MINVALUE 9 –序列最小值9
CYCLE –序列循环,每次增加2,一直到100后回到9从新开始
CACHE 10; –缓存中序列值个数为10
两个属性:语法序列.属性名
Nextval:序列的下一个值 select myseq.nextval from dual
Currval:取序列的当前值 select museq.currval from dual
CURRVAL在被引用之前,必须先使用NEXTVAL来产生一个序列值;
Insert into 表名 values(序列名.nextval)无限的自动插入
3. 修改序列
ALTER SEQUENCE test_seq
INCREMENT BY 4 ——序列每次增加4
MAXVALUE 1000 ——序列最大值1000
- 删除序列
Drop sequence 序列名
练习:
1.创建一个序列,该序列起始值从1开始,无最大值,增量是1,不循环。
CREATE SEQUENCE seq1
INCREMENT BY 1
START WITH 1
2.查询序列的当前值及下一个值
SELECT seq1.nextval FROM dual
SELECT seq1.currval FROM dual
3.使用第1题所建的序列,向部门表中插入两条记录,部门编号使用序列值,
部门名称分别为:Education、Market,城市分别为:DALLAS、WASHTON
INSERT INTO dept VALUES (seq1.nextval,’Education’,’DALLAS’);
INSERT INTO dept VALUES (seq1.nextval,’Market’,’WASHTON’);
SELECT * FROM dept
DROP SEQUENCE seq1
十七、索引
1. 创建索引
手动创建:
Create index 索引名 on 表名(列名[,列名….])
create table employee1(
Pon number(7),
Pname varchar2(20)
)
Create index index_pno on employee1(pno)
函数索引:Create index index_pno on employee1(upper(pname))
Create index index_pno on employee1(pname,pno)
自动创建索引:当创建唯一键或者主键时,会自动创建对应的索引
Rowid:是一个伪列。
2. 删除索引
Drop index 索引名
3. 索引的使用情况
表数据量很大
要查询的结果集在2%-4%左右
经常用来做WHERE条件中的列或者多表连接的列
查询列的数据范围分布很广
查询列中包含大量的NULL值,因为空值不包含在索引中
4.索引缺点:占用空间,降低DML的操作速度
同义词了解:同义词( SYNONYM )
是指向数据库对象(如:表、视图、序列、存储过程等)的数据库指针。
CREATE [PUBLIC] SYNONYM 同义词
FOR [schema.]对象名;
DROP SYNONYM s_emp
练习:
1.使用子查询的方式,创建test表。
CREATE TABLE TEST AS SELECT * FROM emp
create table TEST(
tid number(10),
tname varchar2(20)
)
2.快速复制test表中的数据,复制到100w条左右
INSERT INTO TEST SELECT * FROM TEST
3.更新test表中的tid字段为rownum
UPDATE TEST SET tid=ROWNUM
4. 查询test中empno为800000的记录值,记录查询执行时间。
Select * from test where empno=800000
5.在test表的empno字段上创建索引
CREATE INDEX ind_1 ON TEST(tid)
6.重新执行第4题,对比查询时间
SELECT * FROM TEST WHERE tid=80000
SELECT * FROM TEST WHERE tid=90000
DROP TABLE TEST
DROP INDEX ind_1