oracle数据库(二)_基础使用
1 语法基础
1.1 创表
- 创表
-- 创表
CREATE TABLE student(
sno VARCHAR2(8) PRIMARY KEY
,sname VARCHAR2(8) NOT NULL
,ssex CHAR(1) CHECK(ssex in ('男','女'))
,sbirthday DATE
);
CREATE TABLE sc(
sno VARCHAR2(8) NOT NULL REFERENCES student(sno)
,cno VARCHAR2(8)
,score NUMBER(8,2)
,REFERENCES fk_sc_cno foreign key(sno) references course(cno)
);
CREATE TABLE course(
cno VARCHAR2(8) PRIMARY KEY
,cname VARCHAR2(8) NOT NULL UNIQUE
,tno NUMBER(8,2)
);
-- 复制表结构
CREATE TABLE student2 as (select * from student where 1=2);
-- 复制表结构及数据
CREATE TABLE student2 as (select * from student);
- 约束
primary key
foreign key
default
check
not null
unique
-- 主键约束
ALTER TABLE course ADD CONSTRAINT pk_cno PRIMARY KEY (cno));
ALTER TABLE student DROP CONSTRAINT pk_cno);
-- 外检约束
ALTER TABLE sc ADD CONSTRSINT fk_sno FOREIGN KEY(sno) references student(sno);
ALTER TABLE sc ADD CONSTRSINT fk_cno FOREIGN KEY(cno) references course(cno);
ALTER TABLE sc DROP CONSTRAINT fk_sno);
ALTER TABLE sc DROP CONSTRAINT fk_cno);
-- 检查约束
ALTER TABLE student ADD CONSTRAINT ck_ssex CHECK(ssex in ('男','女'));
ALTER TABLE student DROP CONSTRAINT ck_ssex);
-- 唯一值约束
ALTER TABLE course ADD CONSTRAINT un_cno UNIQUE(cno));
ALTER TABLE course DROP CONSTRAINT un_cno);
-- 空值约束
ALTER TABLE student MODIFY (sname NOT NULL);
ALTER TABLE student MODIFY (sname NULL);
-- 查看表拥有的约束
select * from user_constraints where OWNER = 'SCOTT' AND TABLE_NAME='STUDENT';
- 修改表结构
-- 加列
ALTER TABLE student ADD tmp_ssex VARCHAR2(1);
-- 修改列数据类型(有数据时不能改,添加临时列操作)
ALTER TABLE student MODIFY (tmp_ssex char(1 BYTE) NOT NULL);
-- 改表名
ALTER TABLE student RENAME TO studnet2;
-- 修改列名
ALTER TABLE student RENAME COLUMN tmp_ssex to tmp2_ssex;
-- 删列
ALTER TABLE student DROP COLUMN tmp2_ssex;
-- 删表
DROP TABLE student
1.2 增删改
-- 插入数据
INSERT INTO student VALUES('s001','zz','男',TO_DATE('19950920','YYYYMMDD');
INSERT INTO student(sno,sname,ssex) VALUES('s002','kk','女');
INSERT INTO student2 (SELECT * FROM student);
INSERT ALL
when ssex = '男' then
INTO student2
when ssex = '女' then
INTO student3
SELECT * FROM student; -- select不能加括号,into 后没有逗号
-- 删除数据
TRUNCATE TABLE student;
DELETE FROM student WHERE sno = 's001' ;
-- 修改数据
UPDATE student SET sname = 'zz',ssex = '男' WHERE sno='s001';
update emp1 e1 set (comm,deptno)=(select comm,deptno from emp e where e1.empno=e.empno) [where e1.col = value];
1.3 查
- 连接查询
# 笛卡尔积
SELECT * FROM student,sc;
# 内连接
SELECT * FROM student st,sc WHERE st.sno = sc.sno;
SELECT * FROM student st join sc on st.sno = sc.sno;
# 左外连接
SELECT * FROM student st left join sc on st.sno = sc.sno;
# 右外连接
SELECT * FROM student st right join sc on st.sno = sc.sno;
# 全外连接
SELECT * FROM student st full join sc on st.sno = sc.sno;
- 集合查询
(两边表的列数及列类型需要一一对应,名字可以不同,根据列位置和列类型合并)
INTERSECT
交集 两者共有
UNION
并集 去重
UNION ALL
并集 不去重
MINUS
前有后没有
(SELECT * FROM sc) INTERSECT (SELECT * FROM sc);
- 子查询
子查询可以当作表或条件使用
# select的原理是基于表的每一行迭代出来的
# 此方式最终输出行数会和外层行数一致
select d.*
,(select count(1) from emp where deptno = d.deptno) cnt
from dept d;
select e.*
,(select count(1) from emp where deptno = e.deptno) cnt
from emp e;
# 当表用
SELECT *
FROM
student st,
(SELECT * FROM sc) sc
WHERE st.sno = sc.sno
# 当条件用
SELECT *
FROM
student
WHERE sno in (select sno from sc)
# 当having条件
select deptno
from emp
group by deptno
having count(1) = (select count(1) from emp where deptno = 10);
- 逻辑查询(IN,EXISTS,ANY,ALL)
-- IN
select * from student st where st.sno in (select sno from sc);
-- EXISTS,每行反应一个true或false
select * from student st where exists(select * from sc where st.sno = sc.sno);
-- ANY(SOME)
select * from student st where st.sno = any(select sno from sc);
-- ALL 获取最大年龄的学生
select *
from student
where sage >= all(select sage from student);
- 模糊查询
-- 查询名字包含A的信息
select * from emp where ename like '%A%';
-- 查询名字第二个字母是A的信息
select * from emp where ename like '_A%';
2 函数基础
2.1 数字数
ABS(x)
,绝对值
MOD(x,y)
,求余
POWER(x,y)
,幂函数
CEIL(x)
,向上取整
FLOOR(x)
,向下取整
ROUND(x[,y])
,四色五入,默认取整数
TRUNC(x[,y])
,截断,默认取整数
2.2 字符函数
ASCII(x)
CONCAT(x,y)
,链接连个字符
INSTR(x, str [,start] [,n])
,找到字符存位置
LENGTH(x)
,长度
LOWER(x)
,小写
UPPER(x)
,大写
LTRIM(x[,trim_str])
,左修剪
RTRIM(x[,trim_str])
,右修剪
TRIM([trim_str FROM] x)
,左右修剪
REPLACE(x,old,new)
,替换
SUBSTR(x,start[,length])
,截取字段
REVERSE(x)
,反转字符串
2.3 日期函数
SYSDATE
,系统当前时间
ADD_MONTHS(d,n)
,月的加减法
MONTHS_BETWEEN(d1,d2)
,返回d1-d2的相差月数
LAST_DAY(d)
,返回当月最后一天的相同时间
NEXT_DAY(d,'星期一')
,返回下一个星期一日期
ROUND(d[,fmt])
,四色五入时间,默认取日
TRUNC(d[,fmt])
,切断时间,默认取日
-- 日期截断
SELECT
SYSDATE
,TRUNC(SYSDATE)
,TRUNC(SYSDATE,'DDD') -- 当天,默认格式
,TRUNC(SYSDATE,'DD') -- 当天
,TRUNC(SYSDATE,'D') -- 当周第一天,周日 (DAY,DY)
,TRUNC(SYSDATE,'MM') -- 当月第一天,可以写成'MONTH'
,TRUNC(SYSDATE,'Q') -- 当季第一天
,TRUNC(SYSDATE,'Y') -- 当年第一天,可以写成'YEAR'
FROM DUAL
2.4 转换函数
TO_NUMBER(x[,fmt])
,转换为数值
TO_CHAR(d|n[,fmt])
,转换为字符串
TO_DATE(x[,fmt])
,转换为日期
EXTRACT
,日期转化为数值
-- 数值2字符串
SELECT
TO_CHAR(12345.6,'L999,999.99') 带当地货币符号
,TO_CHAR(12345.6,'$000,000.00') 带美元货币符号
FROM DUAL;
-- 日期2字符串
SELECT
TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') 时间字符串
,TO_CHAR(SYSDATE,'DAY','NLS_DATE_LANGUAGE=American') 星期
,TO_CHAR(SYSDATE,'DY','NLS_DATE_LANGUAGE=American') 星期缩写
,TO_CHAR(SYSDATE,'D','NLS_DATE_LANGUAGE=American') 星期数值
,TO_CHAR(SYSDATE,'Q') 返回季度数字
FROM DUAL;
-- 日期2数值
SELECT
EXTRACT(YEAR FROM SYSTIMESTAMP) YEAR --SYSDATE
,EXTRACT(MONTH FROM SYSTIMESTAMP) MONTH --SYSDATE
,EXTRACT(DAY FROM SYSTIMESTAMP) DAY --SYSDATE
,EXTRACT(HOUR FROM SYSTIMESTAMP) HOUR
,EXTRACT(MINUTE FROM SYSTIMESTAMP) MINUTE
,EXTRACT(SECOND FROM SYSTIMESTAMP) SECOND
,EXTRACT(HOUR FROM (INTERVAL '2 16:16:16' DAY TO SECOND)) --取时间间隔的小时
FROM DUAL;
-- 字符串2日期
SELECT
TO_DATE('1991-09-20 03:00:00','YYYY-MM-DD HH24:MI:SS') 日期
FROM DUAL;
2.5 聚合函数
AVG(col)
:平均
SUM(col)
:合计
COUNT(col)
:计量
MIN(col)
:最小
MAX(col)
:最大
WM_CONCAT(col)
:列值拼接,用逗号分隔
listagg(col,tip) within group (order by col)
:列值拼接,指定分隔符及排序
2.6 通用函数
NVL(col, nval)
:替换带null返回
NVL2(col, val1, val2)
:非空返回v1,空返回v2
NULLIF(a,b)
: null if a==b else other
COALESCE(a,b,...)
:从左往右找到第一个部位null的值
DECODE(col|val, con1, val1, con2, val2, nval)
:字典匹配
CASE col WHEN cv1 THEN v1 WHEN cv2 THEN v2 [...] ELSE ov END
: 条件
CASE WHEN con1 THEN v1 WHEN con2 THEN v2 [...] ELSE ov END
: 条件
3 序列
- 序列不会归零
- 序列可以多表共用,出现抢数现象
- 没有commit的行会出现裂缝
- 修改序列只会对后面的调用有影响
- 不能修改序列的初始值。
- 修改时候最小值不能大于当前值,最大值不能小于当前值
CREATE SEQUENCE myseq
-- [START WITH num] 从某一个整数开始,升序默认值是1,降序默认值是-1
-- [INCREMENT BY increment] 步长
-- [MAXVALUE num|NOMAXVALUE] 最大值10的27次方,-1
-- [MINVALUE num|NOMINVALUE] 最小值1,-10的25次方
-- [CYCLE|NOCYCLE] 是否循环迭代
-- [CACHE num|NOCACHE] 预先在内存生成序列数,更快,默认20个值
--访问下一个值
select myseq.nextval from dual;
--访问当前值
select myseq.currval calue from dual;
--序列修改
ALTER SEQUENCE MYSEQ
MAXVALUE 10000
MINVALUE -300
--删除序列
DROP SEQUENCE MYSEQ;
- 创建一个以自增字段为主键的表
create sequence myseq;
create table increase
(
increase number(8) primary key,
ename varchar2(8)
);
insert into increase select myseq.nextval,ename from emp;
4 同义词
- 可以为表、视图、序列、过程、函数、程序包等指定一个别名
- 私有同义词,只能由当前用户使用
- 公有同义词,可以被所有用户访问
-- 创建同义词
CREATE [OR REPLACE] [PUBLIC] SYNONYM [schema.]synonym_name
FOR [schema.]object_name
-- 删除同义词
DROP [PUBLIC] SYNONYM [schema.]sysnonym_name
5 视图
- 使用视图优点
安全性,隐藏保护底层表
简化,屏蔽复杂的查询逻辑
-- 创建视图
CREATE [or replace][force|noforce] VIEW myview AS (SELECT * FROM student WHERE sno = 's001');
WITH CHECK OPTION -- 修改必须带符合where条件
WITH READ ONLY -- 只读不能修改
-- 删除视图
DROP VIEW myview
6 临时表
- 临时表在不同的session中不能相互访问
- 会话临时表(会话结束删除)
create global temporary table tbl()on commit preserve rows;
- 事务临时表(事务结束删除)
create global temporary table tbl()on commit delete rows;