SQL(Structured Query Language,结构化的查询语言),用来实现关系数据运算的查询,只要是关系型数据库SQL语言就是一条标准的语言系统
SQL语言分类
- 查询语言
用于检索数据库表中存储的行,可以使用SQL中的Select语句编写查询 - 数据操作语言(DML)
insert 添加
update 修改
delete 删除
merge 合并 - 数据定义语言(DDL)
create 创建数据结构的时候使用
alter 修改数据库结构
drop 删除数据库结构
rename 修改表名
truncate 截断表(删除表中的全部数据) - 数据控制语言(DCL)权限
grant 授予其他用户/角色 数据结构的操作权限
revoke 收回..... - 事务控制(TC[L])
将修改的数据永久的保存到表中
commit 永久性保存
rollback 取消所做的修改(回滚)
savepoint 设置保存点,可以回滚到指定的位置
编写SQL语句的规则 - SQL关键字不区分大小写的.
- 对象名和列不区分大小写
- 列中的值区分大小写
逻辑操作符 - and : 条件都为true才为true 否则都为false
- or : 如果任意一个条件为true都为true,否则返回false
- not : 条件是false,返回true,如果条件是true就返回false
SCOTT 用户
SQL> select table_name from user_tables;
TABLE_NAME
------------------------------
SALGRADE
BONUS
EMP 员工表
DEPT 部门表
SQL> desc dept;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
DEPTNO NOT NULL NUMBER(2) 部门编号
DNAME VARCHAR2(14) 部门名称
LOC VARCHAR2(13) 部门地址
SQL> desc emp
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4) 员工编号
ENAME VARCHAR2(10) 员工姓名
JOB VARCHAR2(9) 工种
MGR NUMBER(4) 上司编号
HIREDATE DATE 入职时间
SAL NUMBER(7,2) 工资
COMM NUMBER(7,2) 奖金
DEPTNO NUMBER(2) 部门编号
select * from table_name;
select : 用于指定要检索的列(用于展示的列)
* : 表示所有列
from : 用于指定检索的表
table_name : 查询的表名
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
select <column1,column2,....> from table_name
where expression
where : 用于指定条件语句,如果条件语句返回为true,返回当前行数据,如果为false,这不会显示
expression : 表示条件语句
=
<>,!=
>=
<=
<
between ... and ... 在两个值直接
in 匹配列表中的值
like 模糊查询
isnull 检查null
时间类型比较
-
以Oracle默认时间格式查询(dd-MM月-YY)
SQL> select ename,sal,hiredate from emp where hiredate >'01-1月-82';ENAME SAL HIREDATE ---------- ---------- -------------- SCOTT 3000 19-4月 -87 ADAMS 1100 23-5月 -87 MILLER 1300 23-1月 -82
-
时间转换将字符串转换成时间格式
to_date('1982-01-01','yyyy-MM-dd') 将字符串转换成时间类型
SQL> select ename,sal,hiredate from emp where hiredate >to_date('1982-01-01','yyyy-MM-dd');ENAME SAL HIREDATE ---------- ---------- -------------- SCOTT 3000 19-4月 -87 ADAMS 1100 23-5月 -87 MILLER 1300 23-1月 -82
between...and...
SQL> select ename,sal,hiredate from emp where sal between 1100 and 3000;ENAME SAL HIREDATE ---------- ---------- -------------- ALLEN 1600 20-2月 -81 WARD 1250 22-2月 -81 JONES 2975 02-4月 -81 MARTIN 1250 28-9月 -81 BLAKE 2850 01-5月 -81 CLARK 2450 09-6月 -81 SCOTT 3000 19-4月 -87 TURNER 1500 08-9月 -81 ADAMS 1100 23-5月 -87 FORD 3000 03-12月-81 MILLER 1300 23-1月 -82 已选择11行。
SQL> select ename,sal,hiredate from emp where sal >= 1100 and sal<= 3000;
ENAME SAL HIREDATE
ALLEN 1600 20-2月 -81 WARD 1250 22-2月 -81 JONES 2975 02-4月 -81 MARTIN 1250 28-9月 -81 BLAKE 2850 01-5月 -81 CLARK 2450 09-6月 -81 SCOTT 3000 19-4月 -87 TURNER 1500 08-9月 -81 ADAMS 1100 23-5月 -87 FORD 3000 03-12月-81 MILLER 1300 23-1月 -82 已选择11行。
like "%": 0个到多个字符 "_"单个字符
SQL> select ename,sal,hiredate from emp where ename like 'S%';
ENAME SAL HIREDATE ---------- ---------- -------------- SMITH 800 17-12月-80 SCOTT 3000 19-4月 -87
SQL> select ename,sal,hiredate from emp where ename like '__A%';
ENAME SAL HIREDATE ---------- ---------- -------------- BLAKE 2850 01-5月 -81 CLARK 2450 09-6月 -81 ADAMS 1100 23-5月 -87
逻辑操作符
1. and : 条件都为true才为true 否则都为false 2. or : 如果任意一个条件为true都为true,否则返回false 3. not : 条件是false,返回true,如果条件是true就返回false
查询部门编号20 工种为CLERK
SQL> select ename,job,deptno from emp where deptno = 20 and job='CLERK';ENAME JOB DEPTNO ---------- --------- ---------- SMITH CLERK 20 ADAMS CLERK 20
岗位,MANAGER 工资高于2500
SQL> select ename,job,deptno from emp where sal>2500 or job='MANAGER';
ENAME JOB DEPTNO ---------- --------- ---------- JONES MANAGER 20 BLAKE MANAGER 30 CLARK MANAGER 10 SCOTT ANALYST 20 KING PRESIDENT 10 FORD ANALYST 20 已选择6行。
工种为CLERK,部门编号不是10,30,40
SQL> select ename,sal,hiredate from emp where deptno not in(10,30,40) and job = 'CLERK'
2 ;ENAME SAL HIREDATE ---------- ---------- -------------- SMITH 800 17-12月-80 ADAMS 1100 23-5月 -87
Order By 子句,对行进行排序
select <cloumn1,...> from table_name
where expression
order by column1[,column2...] [asc | desc]
order by : 表示按列名进行排序
asc 升序(默认)
desc 降序
查询部门编号30,安装工资升序排序
SQL> select ename,sal,comm from emp where deptno = 30 order by sal asc;
ENAME SAL COMM
---------- ---------- ----------
JAMES 950
WARD 1250 500
MARTIN 1250 1400
TURNER 1500 0
ALLEN 1600 300
BLAKE 2850
已选择6行。
多列排序
SQL> select ename,sal,comm from emp where deptno = 30 order by sal asc,comm desc;
ENAME SAL COMM
---------- ---------- ----------
JAMES 950
MARTIN 1250 1400
WARD 1250 500
TURNER 1500 0
ALLEN 1600 300
BLAKE 2850
已选择6行。
如果在select语句中同时包含group by,having以及order by ,则必须将order by 放在最后
group by 分组
select <cloumn1,...> from table_name
group by column1[,column2...]
多列分组:
SQL> select job,deptno,count(1) from emp group by job,deptno order by deptno;
JOB DEPTNO COUNT(1)
--------- ---------- ----------
CLERK 10 1
MANAGER 10 1
PRESIDENT 10 1
ANALYST 20 2
CLERK 20 2
MANAGER 20 1
CLERK 30 1
MANAGER 30 1
SALESMAN 30 4
已选择9行。
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
1 7369 SMITH CLERK 7902 1980-12-17 800 20
2 7499 ALLEN SALESMAN 7698 1981-2-20 1600 300 30
3 7521 WARD SALESMAN 7698 1981-2-22 1250 500 30
4 7566 JONES MANAGER 7839 1981-4-2 2975 20
5 7654 MARTIN SALESMAN 7698 1981-9-28 1250 1400 30
6 7698 BLAKE MANAGER 7839 1981-5-1 2850 30
7 7782 CLARK MANAGER 7839 1981-6-9 2450 10
8 7788 SCOTT ANALYST 7566 1987-4-19 3000 20
9 7839 KING PRESIDENT 1981-11-17 5000 10
10 7844 TURNER SALESMAN 7698 1981-9-8 1500 0 30
11 7876 ADAMS CLERK 7788 1987-5-23 1100 20
12 7900 JAMES CLERK 7698 1981-12-3 950 30
13 7902 FORD ANALYST 7566 1981-12-3 3000 20
14 7934 MILLER CLERK 7782 1982-1-23 1300 10
部门编号分组
10 20 JOB 30
CLARK SMITH CLERK ALLEN
KING JONES MANAGER WARD
MILLER SCOTT ANALYST MARTIN
ADAMS CLERK BLAKE
FORD ANALYST TURNER
JAMES
根据部门编号工种分组
20 JOB
SMITH CLERK ADAMS CLERK
JONES MANAGER
SCOTT ANALYST FORD ANALYST
having 子句过滤组
显示平均工资高于2000的部门编号,平均工资,最高工资..
SQL> select deptno,avg(sal) from emp group by deptno having avg(sal) >2000;
DEPTNO AVG(SAL)
---------- ----------
20 2175
10 2916.66667
只保留工资大于1000的行,根据部门分组,保留部门平均工资高于2000的行
SQL> select deptno,avg(sal) from emp where sal > 1000 group by deptno having avg(sal)>2000 order by deptno;
DEPTNO AVG(SAL)
---------- ----------
10 2916.66667
20 2518.75
使用 distinct 来检索唯一的列值
去除列中的重复值
SQL> select job,count(1) from emp group by job;
JOB COUNT(1)
--------- ----------
CLERK 4
SALESMAN 4
PRESIDENT 1
MANAGER 3
ANALYST 2
SQL> select distinct job from emp;
JOB
---------
CLERK
SALESMAN
PRESIDENT
MANAGER
ANALYST
使用运算符:
(+,-,,/)
SQL> select ename,sal(1.2) from emp;
ENAME SAL*(1.2)
---------- ----------
SMITH 960
ALLEN 1920
WARD 1500
JONES 3570
MARTIN 1500
BLAKE 3420
CLARK 2940
SCOTT 3600
KING 6000
TURNER 1800
ADAMS 1320
ENAME SAL*(1.2)
---------- ----------
JAMES 1140
FORD 3600
MILLER 1560
已选择14行。
DML语句
-
insert
insert into table_name [column1,column2,....] values(value1,value2,....);
insert into table_name [column1,column2,...] select (column1,column2,....) from table_name2;insert into : 指明要插入表中的字段
values : 插入相应字段中的值
SQL> create table dept4 as select * from dept where 1!=1;表已创建。
Update
update table_name set column1 = value1[,column2=value2,....] where expression;
SQL> update newemp set sal = sal*1.1 ;
已更新14行。
SQL> select ename,sal from newemp;
ENAME SAL
---------- ----------
SMITH 880
ALLEN 1760
WARD 1375
JONES 3272.5
MARTIN 1375
BLAKE 3135
CLARK 2695
SCOTT 3300
KING 5500
TURNER 1650
ADAMS 1210
ENAME SAL
---------- ----------
JAMES 1045
FORD 3300
MILLER 1430
已选择14行。
SQL> update newemp set sal = sal*1.2 where ename = 'WARD' ;
已更新 1 行。
SQL> select ename,sal from newemp;
ENAME SAL
---------- ----------
SMITH 880
ALLEN 1760
WARD 1650
JONES 3272.5
MARTIN 1375
BLAKE 3135
CLARK 2695
SCOTT 3300
KING 5500
TURNER 1650
ADAMS 1210
ENAME SAL
---------- ----------
JAMES 1045
FORD 3300
MILLER 1430
已选择14行。
-
delete
delete from table_name [where expression];使用delete语句删除表中的数据,并不能释放被善用的数据块空间,它只是把哪些被删除的数据块标记为 Unused,将来还可以回退(rollback)操作.
-
merge
把数据从一个表中复制到另一个表,插入新数据或替换掉旧数据.merge into table11 using table2 on expression
when matched then update..
when not matched then insert ..;SQL> merge into newemp ne
2 using emp e
3 on (ne.empno = e.empno)
4 when matched then
5 update set ne.sal = e.sal
6 when not matched then
7 insert values(e.empno,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.deptno);14 行已合并。
表连接查询
连接查询是指将两个或两个以上的表或试图的查询.在实际应用中,查询单个表可能无法满足需要.
-
简单连接
使用逗号将两个或多个表进行连接.自然连接
自然连接是指使用相等比较(=)指定连接条件,主要用于检索主从表之间的关联数据
select table1.column,table2.column... from table1,table2
where table1.column1 = table2.column2;显示部门名称,员工名称,工资 只显示部门编号为10的
表的别名:
SQL> select dname as 部门名称,ename "员工姓名",sal 员工工资 from dept d,emp e where e.deptno = d.deptno and d.deptno = 10;
部门名称 员工姓名 员工工资 -------------- ---------- ---------- ACCOUNTING CLARK 2450 ACCOUNTING KING 5000 ACCOUNTING MILLER 1300
内连接
内连接用于返回满足条件的记录
select table1.column,table2.column...
from table1 [inner] join table2
on table1.column1 = table2.column2;
SQL> select d.dname,e.ename from dept d inner join emp e on d.deptno = e.deptno;
DNAME ENAME
-------------- ----------
SALES ALLEN
SALES WARD
RESEARCH JONES
SALES MARTIN
SALES BLAKE
ACCOUNTING CLARK
RESEARCH SCOTT
ACCOUNTING KING
SALES TURNER
RESEARCH ADAMS
SALES JAMES
DNAME ENAME
-------------- ----------
RESEARCH FORD
ACCOUNTING MILLER
已选择13行。
外连接
select table1.column,table2.column...
from table1 [left | right] join table2
on table1.column1 = table2.column2;
外连接是内连接的扩展,它不仅会返回满足条件的所有记录,也会返回不满足条件的记录,如果连接表中(主表)有一列空值,也会被显示.
SQL> select d.dname,e.ename from dept d left join emp e on d.deptno = e.deptno;
DNAME ENAME
-------------- ----------
SALES ALLEN
RESEARCH JONES
SALES MARTIN
SALES BLAKE
ACCOUNTING CLARK
RESEARCH SCOTT
ACCOUNTING KING
SALES TURNER
RESEARCH ADAMS
SALES JAMES
DNAME ENAME
-------------- ----------
RESEARCH FORD
ACCOUNTING MILLER
吃饭部
OPERATIONS
已选择15行。
SQL> select d.dname,e.ename from dept d ,emp e where d.deptno = e.deptno(+);
DNAME ENAME
-------------- ----------
SALES ALLEN
SALES WARD
RESEARCH JONES
SALES MARTIN
SALES BLAKE
ACCOUNTING CLARK
RESEARCH SCOTT
ACCOUNTING KING
SALES TURNER
RESEARCH ADAMS
SALES JAMES
DNAME ENAME
-------------- ----------
RESEARCH FORD
ACCOUNTING MILLER
吃饭部
OPERATIONS
已选择15行。
自连接
同一张表之间的连接查询
SQL> select m.ename||' 是 '||e.ename||' 领导!' from emp m,emp e where m.mgr = e.empno;
M.ENAME||'是'||E.ENAME||'领导!
------------------------------
FORD 是 JONES 领导!
SCOTT 是 JONES 领导!
JAMES 是 BLAKE 领导!
TURNER 是 BLAKE 领导!
MARTIN 是 BLAKE 领导!
WARD 是 BLAKE 领导!
ALLEN 是 BLAKE 领导!
MILLER 是 CLARK 领导!
ADAMS 是 SCOTT 领导!
CLARK 是 KING 领导!
BLAKE 是 KING 领导!
M.ENAME||'是'||E.ENAME||'领导!
------------------------------
JONES 是 KING 领导!
SMITH 是 FORD 领导!
已选择13行。
SQL> select m.ename,e.ename from emp m,emp e where m.mgr = e.empno;
ENAME ENAME
---------- ----------
FORD JONES
SCOTT JONES
JAMES BLAKE
TURNER BLAKE
MARTIN BLAKE
WARD BLAKE
ALLEN BLAKE
MILLER CLARK
ADAMS SCOTT
CLARK KING
BLAKE KING
ENAME ENAME
---------- ----------
JONES KING
SMITH FORD
已选择13行。
交叉连接(笛卡尔积)
数据库事务
事务的开始于结束:
连接到数据库上,并执行一条DML语句(insert,update或delete)
前一个事务结束后,又输入一个DML语句.
事务(Transaction) 是由一组(多条)SQL语句组成的最小逻辑工作单元.
事务是为了保证数据的一致性.
事务的提交和回滚
要永久性的记录事务中SQL语句的结果,需要执行commit语句,从而提交事务.
事务结束:
执行commit或rollback语句.
执行一条DDL语句,create table,都会自动提交commit;
断开数据库的连接,退出sqlplus时,输入exit的时候 都会被commit.
如果sqlplus 被意外终止了,计算机蓝屏,会自动执行rollback语句.
执行一条DML语句,该语句失败,这种情况,会执行rollback语句;
只有DML存在事务的概念,DDL和DCL没有事务的概念,执行就被提交.
设置保存点:
保存点就是事务中标记.把一个较长的事务分为多个较短的事务.可以回滚到制定的保存点.
savepoint savepoint_name;
事务的ACID特性:
- 事务的概念;事务是把对数据库的一系列操作都看做一个整体,要么全部成功,要么全部失败,利用事务我们可以保证数据库的完整性,
- 原子性(Atomic) 事务是原子的,这就是说事务中包含的所有SQL语句都是一个不可分割的工作单元.
- 一致性(Consist) 事务必须确保数据库的状态保存一致,事务开始时,数据库的状态是一致的,事务结束时,数据库的状态也必须是一致的.
- 隔离性(Isolated) 多个事务可以独立运行,而不会彼此影响.
- 持久性(Durable) 一旦事务被提交后,数据库的变化就会被永久记录,即使数据库软件崩溃.
并发事务:
数据库支持多个用户同时对数据库进行交互,每个用户都可以同时运行自己的事务,这种事务就称为并发事务
用户同时运行多个事务,而这些事务对同一张表产生影响.那么这些事务是互相独立的.
直达执行一条commit才会彼此产生影响.
事务锁:
当多个事务对同一条数据进行操作的时候,就会产生事务锁.
第二个事务必须等待第一个事务释放该锁(提交/回滚);
并发事务会产生的问题:
事务隔离级别:
是一个事务对数据库的修改与并行的另外一个事务的隔离程度.
两个并发事务T1和T2正在访问相同的行数据.
幻象读取:
事务T1读取一条指定的where子句返回的结果集.然后事务T2新插入一行数据,这行
恰好可以满足T1查询的where条件.然后T1又使用相同的查询再次对表进行查询,但
此时看到了事务T2刚才插入的新行,这个新行就称为"幻象"
不可重复读:
事务T1读取一行数据,紧接着T2修改了T1刚才读取的哪一行数据.然后T1再次读取的时候,
发现刚才读取的结果不同的了.这种现象称为 " 不可重复读".
脏读:
事务T1更新了一行数据,但是并没有提交所修改的内容,事务T2读取更新后的行,然后T1回滚操作,
取消了刚才所做的修改,先T2所读取的行就无效了.这种现象"脏读".
因为在T2读取这行数据的时候,T1所做的修改并没有提交.
隔离级别 从低到高
read uncommitted 幻读,不可重复读和脏读都允许
read committed 允许幻读和不可重复读,但是不允许脏读
reoeatabke read 允许幻读,但是不允许不可重复读和脏读
serializable 幻象读,不可重复读和脏读都不允许
Oracle 数据库只支持read committed和serializable两种事务隔离级别.
set transaction isolation level
{
read committed|
serializable
}