数据库 DataBase
关系数据库管理系统 RDBMS
数据库的功能: 存储和管理数据。
数据库较文本文件
文本文件存储数据的缺点:没有数据类型,只能存储字符串;查询数据不方便;不适合存储大数据量;不安全
数据库的优点:它克服了文本文件的以上缺点之外,还可以供多用户同时访问。
数据库的工作模式:使用SQL语言进行通信:Structed Query Language(结构化查询)
连接oracle步骤:
1. 登陆,利用telnet命令
2. 键入sqlplus username/password
3. 执行sql命令对数据进行CURD操作
4. 退出exit (断开连接,退出客户端程序)
对数据库的基本操作:
因为数据库中存储数据的单位是表(table),所以我首先讲的是对表的基本操作。
1.建表sql
语法:create table( columnname type constrain);
2.删表sql
语法:drop table tablename;
3.对表的增删改查。具体细节,后面将作详细介绍。
将成批的sql语句放在.sql文件中,可用命令start/@ 路径/文件名 的方式批量执行
其它常用操作:
1.查看当前用户下有哪些表:select table_name from user_tables;
2.获得表的结构:desc 表名 desc是describe的简写
3.查询表中数据 可用 select 列名,列名,... from 表名
sqlplus命令与sql命令的区别:
1. 执行的客户端不一样。
2. sqlplus命令可以不以;作为结束,sql命令必须以;结束。
sqlplus命令:exit,desc 表名,start (@)文件名
col 列名 format 格式(控制查询结果显示):
col empno format 9999
col sal format 9999.99
col job format a10
set pagesize 200
/ 执行最近一次sql命令
list 显示最近一次sql命令
c/旧值/新值 修改最近一次sql命令
conn 用户名/密码 切换用户
help index 显示帮助
CURD操作
select查询
常规查询:select 列1,列2,.... from 表名 where 条件;
注意其中列名如果是表的全部列,则可用*代替,不过它比直接写列名在执行效率上要慢。
在sql语句中如果要用到字符串,则需使用''括起来,并且字符串的比较是区分大小写的。
在条件子句中如果用逻辑运算符,记住它们是有优先级别的:优先级not> and > or,所以可用()来改变优先级
模糊查询:like 字符串,e.g:
查询姓名中第二个字母是A的员工:select * from emp where ename like '_A%';
在模糊查询中有两种通配符:% 表示匹配0到多个任意字符;_表示匹配1个任意字符
查询语句中可用的函数
一般函数sql:
1.select 100 + 200 (as) result from dual; //dual为系统表,它只有一行一列。result为列的一个别名,as可以省略不写
2.select abs(-4738) from dual;//abs()函数是求绝对值的
3.select mod(10, 3) from dual;//mod()函数是求模(余数)的
4.select dbms_random.random() from dual;//dbms_random.random()用来生成随机数
例:随机生成一个1000以内的正整数:
select mod(abs(dbms_random.random()),1000 ) from dual;
字符串函数
1.连接字符串
select 'abc' || 'def' from dual;
select concat('abc','def') from dual;
select empno || '/' || ename || '/' || job from emp;
2.大小写转换:lower(),upper()
select upper('fdjk') from dual;
3.select instr('abcdefg', 'c') from dual;ans:3
//instr 求子串在字符串中的初始位置(注意它是从1开始的)
4.select substr('abcdefg', 4) from dual;ans:defg
//substr用来截取字符串,注意它也是从1开始的
5.select length('abcdefg') from dual;//length()是用来求字符串长度的
日期函数
1.select sysdate from dual;//sysdate表示的是当前日期,它的类型在oracle里为date类型
2.to_char(日期, '格式') 将日期转换为字符串
select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual;
select to_char(sysdate, 'q') from dual;//季度
select to_char(sysdate, 'd') from dual;//一个星期的第几天(注意:以周日为1开始计算)
select to_char(sysdate, 'day') from dual;//星期几
select to_char(sysdate, 'am') from dual;//上下午
select to_char(sysdate, 'mon') from dual;//月份
日期的默认格式为:dd-mon-yy;
3.trunc (截断日期) 返回值还是日期
select trunc(sysdate, 'year') from dual;//今年的1月1号0时0分0秒
select trunc(sysdate, 'month') from dual;
select trunc(sysdate, 'day') from dual;
4.对时间的加减
select sysdate - 5 from dual;//日期+ -时,它以天为单位的
select to_char(sysdate + 1/24,'hh24:mi:ss') from dual;//将当前间加1小时
select add_months(sysdate, -1) from dual;//对月进行减一
其它函数
1.对某列进是否为null的条件选择,可用is null,is not null e.g:
select * from emp where comm is not null;
2.对有可能取值为null的列进行运算时,需用到nvl()函数
e.g: select (sal+nvl(comm,0))*12 asal from emp;
//nvl(检查值,替代值) 如果某列的值等于检查值时,用替代值替代,此例是将null值替换成0,在Oracle中null是指无穷大
组函数:
max() 求某列的最大值;min(),求某列的最小值; avg() 求某列的平均值; sum() 求某列值的和; count() 求某一列取值不为null的个数
select distinct job from emp;//distinct 去除重复取值
select count(distinct job) from emp;//去除重复记录后,求个数
order by:对查询结果进行排序
select * from emp order by comm desc/asc;
中文排序
order by nlssort(列, '格式');
拼音 'NLS_SORT=SCHINESE_PINYIN_M'
笔画 'NLS_SORT=SCHINESE_STROKE_M'
部首 'NLS_SORT=SCHINESE_RADICAL_M'
e.g: select * from product order by nlssort(productname, 'NLS_SORT=SCHINESE_PINYIN_M' );
group by: 分组
语法:group by 列1, 列2-->根据group by 之后的列,取值归为一组,配合组函数求每组的最大值,最小值...
e.g: select max(sal) from emp group by deptno;
注意:如果使用了group by分组,则在select子句中出现的列必须是在group by子句中有的,如果不是,则必须配合组合函数一起使用
按多列分组:select count(*), deptno, job from emp group by deptno, job;
group by...having... 分组之后再进行条件选择
e.g:select max(sal) ,deptno from emp group by deptno having (max(sal) > 3000); //求每个部门最高工资大于3000的最高工资和部门编号
注意:where子句也能达到条件选择的效果,如果where和having都能达到要求,从效率角度出发,应优先选择where; 如果只能在分组之后才可以进行条件选择的话,则使用having。
伪列 (rowid, rownum) 不真正存在于表中的列
select empno,ename,rowid from emp;
rowid 特点:
每张表中的rowid取值没有重复
每个rowid对应一条记录,可以看做是此记录的唯一标识
通过rowid 能够最快速地查找到记录
rownum 为每条查询结果产生一个编号
e.g: select empno,ename,rownum from emp;
查询前5条记录
select empno,ename,rownum from emp where rownum <=5;
select empno,ename,rownum from emp where rownum > 5;(错)
select empno,ename,rownum from emp where rownum = 5;(错)
注意:rownum用作比较条件时只能使用<或者<=比较;特例=1, >=1可以
select empno,ename,rownum from emp where rownum <=5;
语法顺序
select ... from ... where 条件 group by ... having 条件 order by ...
执行顺序
where > group by > having> select >order by
子查询
在很多时候单一的查询不能完成实际的要求,而子查询可以完对单表的复杂查询
1.将子查询结果作为主查询的条件,e.g:
select * from emp where sal = (select max(sal) from emp);//查询具有最高工资的员工信息
select * from emp where sal > (select avg(sal) from emp);//查询所有工资高于平均工资
select * from emp where sal in (select max(sal) from emp group by deptno);//查询每个部门工资最高的员工信息
2.将子查询结果作为一张临时表,作进一步的查询
e.g: select e.*,rownum from (select * from emp order by sal desc) e where rownum <=5;//查询工资最高的前五名员工
select * from (select empno,ename,sal,rownum r from (select * from emp order by sal desc) where rownum <=10) where r > 5;//查询工资最高的6-10名员工
连接查询 (实际开发):从两张或更多张表中查询到数据
1. 内连接
e.g: select empno, ename ,d.deptno, dname from dept d inner join emp e on (e.deptno = d.deptno);
2.(左)外连接
e.g: select empno, ename , d.deptno, dname from dept d left outer join emp e on (e.deptno = d.deptno);
3.(右)外连接
e.g: select empno, ename , d.deptno, dname from dept d right outer join emp e on (e.deptno = d.deptno);
4.自连接
e.g: select e1.ename, e2.ename from emp e1 left join emp e2 on e1.mgr = e2.empno;
5. 多表连接:就是利用以上连接将多个表连接起来
建表
create table 表名(
列名1 数据类型 约束,
列名2 数据类型 约束,
列名3 数据类型 约束,
....
列名n 数据类型 约束
);
在建表时可设定列的默认值,语法如下: 列 数据类型 default 默认值 约束
建表示例:
create table users_jone(
username varchar2(20) primary key,
password varchar2(20) not null check ( length(password) >=4 ),
birthday date,
married number(1) check (married in(0,1)),
age number(3) check (age >0 and age<150),
salary number(7,2) check (salary >0.0)
);
Oracle中数据类型有如下几种:
1.字符串类型: varchar2(字符个数); clob 字符型大对象 (需补充对这两种类型的分析)
2.日期类型: date 年月日,时分秒,毫秒; timestamp 可以到纳秒
3.布尔类型:可将数据类型设定为number(1)或者是char(1),在Oracle里是0和1来表示false和truth的 ,之后可设检查约束为:check(列名 in(0,1))
4. 数字
整数 integer(整数位数) e.g:age integer(3)
小数 number(最大有效数字长度,小数点后位数) e.g:salary number(7,2)//99999.99
Oracle中的约束
作用:保证数据的有效性和完整性
种类:not null 非空约束;unique 唯一约束;primary key 主键约束(唯一并且非空,在一张表里只能有一个主键);check(条件) 检查约束
添加(插入)数据
语法1:insert into 表名(列名1,列名2...) values(值1,值2 ...);
语法2:insert into 表名 values(值1,值2 ...);//在插入给出的所有列的数值时使用,注意值的顺序必须与列名顺序一致
语法3:插入部分列的值 语法:insert into 表名(列名1,列名2...) values(值1,值2 ...);//注意:此时不能省略列名
对事务的操作:
commit; //在对表进行增删改操作后,需执行commit之后才能让所作操作对其他用户可见。
rollback;//若想取消对表的增删改操作,可以执行此语句。
update 更新
语法:update 表 set 列=值, 列=值,... where 条件;
e.g: update emp set sal=800,comm=500 where empno=7369;
delete 删除
语法:delete from 表 where 条件;
e.g: delete from emp where empno = 1234;
delete from 表; -- 删除表中所有记录
truncate table 表名; -- 删除表中所有记录 注意:无法使用rollback 撤销,但运行效率高
注意:如果两张表存在着关联关系,则先删从表记录,再删主表记录。创建这样的有着关联关系的表时,则要先建主表,再建从表。
e.g:create table users_jone; (主) create table orders_jone; (从)
drop table orders_jone; (从) drop table users_jone; (主)
drop table users_jone cascade constraint;//cascade constraint的作用是先删除相关的外键约束再删除表
根据旧表创建新表
做法1:先创建与旧表一样的表结构,然后执行:insert into 新表名 select * from 旧表名;commit;
做法2: 语法:create table 新表名 as select * from 旧表; commit;
注意:此法创建的表结构与旧表几乎一致,只是约束只能复制not null约束。
e.g:create table emp_jone as select * from emp;
create table emp_jone as select * from emp where 1=2;//仅仅复制了表结构,没有复制表数据
约束:
1.行级约束
primary key, references,unique, check, not null
2.表级约束
primary key, references,unique, check
表级约束的写法,e.g:
create table orders_jone(
orderId number(6) ,
orderDate date not null,
state number(1) not null ,
totalPrice number(10,2) not null,
username varchar2(20) not null,
primary key (orderId),
check (state in(1,0)),
foreign key (username)
references users_jone(username)
);
create table score(
stuName varchar2(20),
courseName varchar2(20),
score number(3) not null,
primary key(stuName, courseName)//联合主键
);
约束命名
命名规则: 表名_列名_约束类型简写(PK 主键,NN 非空,CK 检查,UK 唯一,FK 外键)
如果没有给约束起名,oracle会自动为约束命名
e.g:create table orders_jone (
orderId number(6)
constraint orders_jone_orderId_pk primary key,
orderDate date
constraint orders_jone_orderDate_nn not null,
state number(1) not null
check (state in(1,0)),
totalPrice number(10,2) not null,
username varchar2(20) not null
constraint orders_jone_username_fk
references users_jone(username)
);
外键约束:限制某一列不能是任意的,必须来源于另外一个主键列
语法:列 数据类型 references 表名(引用列)
系统表(数据字典):存储的都是与定义(表的,约束的)有关信息
user_tables 存储当前用户创建的表相关信息
TABLE_NAME -> 表名
e.g:select table_name from user_tables;
user_constraints 存储了当前用户的所有约束信息
OWNER -> 拥有(创建)者
CONSTRAINT_NAME -> 约束名
CONSTRAINT_TYPE -> 约束类型
TABLE_NAME -> 约束所在表
user_cons_columns 存储了当前用户的所有约束信息
COLUMN_NAME -> 约束所在列
select owner,constraint_name,constraint_type from user_constraints where table_name='ORDERS_jone';
select column_name from user_cons_columns where CONSTRAINT_NAME ='SYS_C0032843';
序列(sequence ): oracle提供的产生唯一值的一种机制
创建语法:create sequence 序列名 选项; e.g: create sequence orders_jone_seq;
select orders_jone_seq.nextval from dual;//取得序列的下个一值
选项:start with 初始值 ; increment by 递增值 ; cache 缓存值
e.g: create sequence orders_jone_seq start with 300001 increment by 2 cache 10;
user_sequences(保存用户的序列信息):
SEQUENCE_NAME -> 序列名,INCREMENT_BY -> 递增值,CACHE_SIZE -> 缓存值
e.g:select * from user_sequences where sequence_name ='ORDERS_jone_SEQ';
应用:可以利用序列生成唯一的ID值。
e.g:insert into orders_jone values(orders_jone_seq.nextval,sysdate,0, 1000.00, 'liucy');
注意点:
1.例如:create sequence orders_jone_seq start with 30000;
select orders_jone_seq.currval,orders_jone_seq.nextval,orders_jone_seq.nextval from dual;//30000,30000,30000
结论:如果一条查询语句中多次出现nextval,则实际取值时只从序列中取了一次值
2.序列第一次使用时不能使用currval
序列刚创建后,运行select orders_jone_seq.currval from emp;
会报错误: 序列 ORDERS_JONE_SEQ.CURRVAL 尚未在此会话中定义
sql语句的分类
DQL (数据查询语言data query) select
DML (数据操控) insert, update, delete
TCL (事务控制语言transaction control) commit, rollback
DDL (数据定义data defination) create, drop, alter, truncate
DCL(数据控制) grant, revoke
alter
添加列 例:alter table users_jone add address varchar2(20) default '北苑家园' not null;
删除列 例:alter table users_jone drop column address;
重命名 例:alter table users_jone rename column address to addr;
修改列 例:alter table users_jone modify username varchar2(30);
删除约束 例:alter table orders_jone drop constraint orders_jone_orderId_pk;
修改约束 例:alter table employees modify manager_id integer;
添加约束 例:
alter table orders_jone add constraint orders_jone_orderId_pk primary key(orderId);
事务 (transaction)
事务代表一组原子(不可再分)操作,它当中的一到多条增删改语句必须作为一个不可分割的整体若,要么都成功(commit),若其中一条失败,应当撤销所有操作(rollback)。
事务的边界(开始和结束)
执行update, insert , delete 时事务开始
执行commit/rollback (事务结束)
rollback只会撤销本次事务所做的所有操作,不会影响已经结束的事务
select 不会受事务影响
锁 synchronize:作用:用来保护并发操作下的数据完整性。(需补充)
事务的4特性:ACID
A - 原子性
C - 一致性
事务开始前和结束后的数据状态应当一致
I - isolation 隔离性
D - 持久性
指事务结束后,数据的状态应当永久保存下来
oracle 数据库对象
表 (table)
序列 (sequence)
约束 (constraint)
视图 (view)
索引 (index)
函数 (function)
(存储)过程(procedure)
对视图,索引,过程等数据库对象方面的使用有待补充。