1. Oracle的表对象

一、Oracle概述

 

使用Oracle数据库的好处:

1) Oracle的运行效率比MySQL数据库好高;
2) Oracle数据库安全性最高;
3) Oracle数据库对分布式的支持非常好;

 

二、Oracle数据库的安装

2.1 Oracle数据库的下载

下载地址:https://www.oracle.com/downloads/index.html

2.2 安装Oracle数据库的准备工作

1) 保证磁盘有足够的空间;
 
2) 足够的内存空间。建议:把运行中的软件关闭,包括:防火墙和杀毒软件;

2.3 安装Oracle数据库

查看oracle11g的安装和卸载此文章

2.4 Oracle服务

打开服务窗口:控制面板》管理工具》服务,或者在运行中输入“services.msc”命令。然后找到全部以Oracle开头的服务。
 

只需要开启以下两项即可:

OracleServiceXXX:Oracle的核心服务。如果要访问Oracle数据库就必须要启动该服务。(必须启动)

OracleOraDb11g_home1TNSListener:监听器服务。如果要使用图形化工具访问Oracle数据库就必须要启动该服务。(建议启动)

三、连接Oracle数据库

3.1 使用Oracle自带SQLPlus工具

 

 


输入用户名scott和密码tiger,然后回车。

 

如果看SQL>提示符就代表连接成功!

3.2 使用Oracle自带的SQLDeveloper工具

打开SQLDeveloper工具:
 
第一次启动SQLDeveloper工具的时候,需要指定JDK1.8的根路径。
 
主界面:
 
接着,点击左上角绿色的加号 ,然后输入数据库连接信息。
 
主机名:访问Oracle数据库的地址。本地地址就是localhost;如果要访问远程Oracle数据库服务器就要输入服务器的IP地址;
SID:Oracle数据库的实例名,例如:orcl

输入完成之后,然后点击“连接”。
 
如果看到左边出现了菜单树,就代表登录成功!

3.3 使用JDBC访问Oracle

使用JDBC的步骤:
第一步:把数据库的驱动包导入到工程里面;
 
第二步:加载驱动;
第三步:获取数据库连接;
第四步:创建Statement对象;
第五步:编写SQL语句,然后就执行SQL语句;
第六步:遍历结果集;
第七步:关闭资源(ResultSet、Statement、Connection);
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/*
	使用JDBC的步骤:
		第一步:把数据库的驱动包导入到工程里面;
		第二步:加载驱动;
		第三步:获取数据库连接;
		第四步:创建Statement对象;
		第五步:编写SQL语句,然后就执行SQL语句;
		第六步:遍历结果集;
		第七步:关闭资源(ResultSet、Statement、Connection);
*/
public class Demo1 {
	public static void main(String[] args) {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			//加载驱动(JDBC4.0)
			//Class.forName("oracle.jdbc.OracleDriver");
			//获取数据库连接
			conn = DriverManager.getConnection(
					"jdbc:oracle:thin:@localhost:1521:orcl",  //Oracle的URL地址
					"scott",  //用户名
					"tiger"); //密码
			//创建Statement对象
			stmt = conn.createStatement();
			//编写SQL并执行
			rs = stmt.executeQuery("select * from emp");
			//遍历结果集
			if (rs != null) {
				while (rs.next()) {
					int empno = rs.getInt("empno");
					String ename = rs.getString("ename");
					System.out.println("编号:" + empno + ",姓名:" + ename);
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			//关闭资源
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}


}

四、常用的SQLPlus命令


五、DDL(数据定义语言)

DDL命令:创建表、修改表、删除表。

5.1 创建表

* 语法结构:

create table 表名 (
列 数据类型 [primary key] auto_increment,
列 数据类型 [default 默认值] [not null],
…,
constraint 约束名 约束类型(列),

);

Oracle数据库的数据类型:


* 约束类型:

唯一约束、非空约束、主键约束、外键约束、check约束。check约束就是用来限制某一列的值。

注意:在Oracle数据库中没有auto_increment关键字。使用序列来实现主键的自增长(后面章程有讲解)。
--创建表
create table student (
  id number(10) primary key,
  name nvarchar2(20) not null,
  gender nchar(1) default '男',
  constraint uni_student_name unique(name),
  constraint chk_student_gender check(gender in ('男', '女'))
);

5.2 复制表

*语法格式:

create table 表名
as

select语句;

--复制表(结构和数据)
create table student_bak
as
select * from student where 1=2;

5.3 修改表

*添加列

alter table 表名
add (列名 数据类型 [not null]);
--添加列
alter table student
add(score number(3));
注意:如果表里面已经有数据,那么添加新的列就不能够指定not null约束。

*修改列的数据类型

alter table 表名
modify(列名 数据类型 [not null]);
--修改列的数据类型
alter table student
modify(name nvarchar2(50));

*修改列名

alter table 表名
rename column 旧列名 to 新列名;
--修改列名
alter table student
rename column name to student_name;

*删除列

alter table 表名
drop(列1, 列2, …);
--删除列
alter table student
drop(score);

5.4 删除表

*语法格式:

drop table 表名 [purge];
--删除表
drop table stduent;
drop table student purge; --永久删除
注意:如果指定了purge参数,那么删除表的时候就不会保留在回收站里面。

六、DML(数据操作语言)

6.1 添加数据

* 语法格式:

insert into 表名(列1, 列2, …)
values(值1, 值2, …);
--添加数据
insert into emp(empno, ename)
values(1000, 'JACKY');

6.2 复制数据

*语法格式:

insert into 表1(列1, 列2, …)
select 列1, 列2, … from 表2;
--复制表
insert into student_bak(id, name)
select empno, ename from emp;
注意:复制表和被复制表的列的数量和类型要保持一致。

6.3 修改数据

* 语法格式:

update 表名 set 列1=值1, 列2=值2, … [where条件];
--修改表的数据
update emp
set ename = '张三'
where empno = 1000;

6.4 删除数据

*语法格式:

delete from 表名 [where条件];
--删除数据
delete from student_bak;

*delete和truncate命令的区别:

1) delete命令先把要删除的数据查询出来,然后再进行删除;truncate命令先把整个表删除,然后再重新创建表;因此,如果删除的数量很多,那么truncate命令的执行效率比delete命令要高;

2) delete命令可以删除指定数据;truncate命令只能够把整个表删除;

七、DQL(数据查询语言)

7.1 多表查询

多表查询:同时查询两张或两张以上的表。

*执行多表查询的注意事项:

1) 执行多表查询的时候,一张表的每一行记录会跟另外一张表的每一行记录进行组合,然后产生新的记录,这种现象也称为“笛卡尔积”现象。
2) 笛卡尔积现象会产生许多的垃圾数据,因此在实际开发中要尽量避免笛卡尔积现象。如果要消除笛卡尔积,那么只需要在执行多表查询的时候添加连接条件:就是一个表的外键列等于另外一个表的主键列。

注意:执行多表查询的时候就一定会出现笛卡尔积现象。如果要消除笛卡尔积就必须要添加连接条件。

多表查询分为:内连接和外连接。

7.1.1 内连接

内连接分为:等值连接和非等值连接。
等值连接就是指连接条件使用等号的连接。
非等值连接就是指连接条件使用<, <=, >, >=, <>符号的连接。

7.1.2 外连接

7.1.2.1 左外连接
左连接:左边的表作为主表,无论条件是否满足,主表的数据都会被查询出来。
*语法格式:
select 列信息 from 表1 left join 表2 on 连接条件;
--查询所有员工的信息以及该员工所在部门名称,无论员工的部门编号是否存在,员工的记录都会被查询出来。(左连接)
select emp.*, dept.dname
from emp left join dept
on emp.deptno = dept.deptno;
注意:left join左边的表是主表。
7.1.2.2 右外连接
右连接:右连接就是右边的表作为主表,无论条件是否满足,主表的数据都会被查询出来。
*语法格式:
select 列信息 from 表1 right join 表2 on 连接条件;
--查询所有员工的信息以及该员工所在部门名称,无论部门是否存在,部门的记录都会被查询出来。(右连接)
select emp.*, dept.dname
from emp right join dept
on emp.deptno = dept.deptno;
注意:right join右边的表是主表。

除此以外,外连接还可以这样:
select 列信息 from 表1, 表2 where 表1.列1 = 表2.列2(+);
如果没有加号的一方就是主表。有加号的一方就是从表。这种写法是Oracle方言。一般不推荐使用。
--oracle方言
select emp.*, dept.dname from emp, dept where emp.deptno(+) = dept.deptno;

7.2 分组查询

*语法结构:

select 组信息 from 表名 group by 分组字段 [having 分组条件];
--需求:查询每一个部门的平均工资
select deptno, avg(sal)
from emp
group by deptno;
组信息:分组字段或聚合函数。

面试:

*什么时候使用where条件,什么时候使用having条件?

如果是分组前的条件就使用where,如果是分组后的条件就使用having。

*select语句:select、from、where、group by、having、order by。

它们的执行顺序:from > where > group by > having > select > order by。

--需求:统计每一个部门工资大于2000的人数
select count(*)
from emp
where sal > 2000
group by deptno;

--需求:统计每一个部门工资大于2000的人数,但是该部门的人数必须要大于1。
select count(*) as total
from emp
where sal > 2000
group by deptno
having count(*) > 1
order by total asc;

7.3 子查询

子查询:在一个查询中嵌套另外一个查询。
按照子查询返回的结果:
a) 单行单列:可以放在where后面作为一条条件。
--需求:查询工资大于30部门最高工资的员工信息
Select max(sal) from emp where deptno = 30 ; -----2850
Select * from emp where sal > 2850;
===================================================================
select * from emp where sal > (select max(sal) from emp where deptno = 30);

b) 单行多列:可以放在where后面作为一个条件。
--需求:查询职位、部门编号与SCOTT用户的职位和部门编号相同的员工信息。
select job, deptno from emp where ename = 'SCOTT'; -----analyst 20
select * from emp where job = “analyst” and deptno = “20”;
==============================================================
select * from emp where (job, deptno) = (select job, deptno from emp where ename = 'SCOTT');

c) 多行单列:可以放在where后面作为一个条件。
--需求:获取所有所在地是NEW YORK的员工信息
select deptno from dept where loc = 'NEW YORK'; -----50 10
select * from emp where deptno in (50,10);
=================================================================
select * from emp where deptno in (select deptno from dept where loc = 'NEW YORK');

d) 多行多列:可以作为一个临时表放在from后面。
--需求:查询所有员工的姓名、职位、工资、所在部门的平均工资
select deptno, avg(sal) avgSal from emp group by deptno; ----查询出每个部门的平均工资
====================================================
select e.ename, e.job, e.sal, t.avgSal 
from emp e, (select deptno, avg(sal) avgSal from emp group by deptno) t 
where e.deptno = t.deptno;

除此以外,子查询还可以放在select后面作为一列。
--需求:查询所有员工的姓名、职位、工资、所在部门的平均工资
select e.ename, e.job, e.sal, (select avg(sal) from emp where deptno = e.deptno) from emp e;

八、伪表和伪列

8.1 伪表dual

伪表就是是一个虚拟的表。它的作用就是用来构造一个符合SQL语法的select语句。
--查询当前用户
select user from dual;


--查询系统时间
select sysdate, systimestamp from dual;


--调用函数
select to_char(sysdate, 'yyyy-MM-dd') from dual;


--执行运算
select 1+2 from dual;

应用场景:1)查询系统参数;2)调用函数;3)执行运算:4)生成或查询序列的值;

8.2 伪列rowid(了解)

当用户往Oracle数据库添加数据的时候,Oracle数据库会为该条数据生成一个ID,该ID是该条记录在磁盘上的物理地址。
 
伪列rowid的作用就是标识每一行的记录。正常情况下,一般用户是不会使用rowid获取某一条记录。

8.3 伪列rownum(重点)

当用户查询数据库的时候,Oracle数据库会对每一条记录从1开始进行编号。然后把该编号保存在rownum列中。它的作用:实现分页功能。

注意:如果使用rownum作为条件,是不可以使用>, >=, =符号。因为每次查询的时候,rownum的值都不一样。

*分页的实现思路:

先查询前面10条的记录。然后再查询的结果作为一个临时表。接着再从临时表的第6条记录开始查询。
--查询emp表的第二页数据,每页显示5条记录
select *
from (select rownum r, emp.* from emp where rownum <= 10)
where r >= 6;

九、运算符

9.1常用的运算符 

算术运算符:+ - * / 
比较运算符:> >= <= < = != in between…and… is null is not null 
逻辑运算符:and or not 
连接运算符:|| 
集合运算符: 
    1) 并集:union(去重复)、union all(有重复) 
    2) 交集:intersect 
    3) 减集:minus 
--查询员工的年薪(工资*12+奖金) 
select ename, sal * 12 + comm as 年薪 from emp; 
 
--工资大于 2000 的员工信息 
select * from emp where sal > 2000; 
 
--工资大于等于 2000,而且工资小于等于 3000 的员工信息 
select * from emp where sal between 2000 and 3000; 
 
--查询所有奖金不为空的员工信息 
select * from emp where comm is not null; 
 
--查询员工的职位信息 
select ename || '的职位是:' || job from emp; 
 
--查询工资大于 1000 并且小于 2500 的员工名字 
select ename from emp where sal > 1000 and sal < 2500; 
 
--查询工资大于 2000 并且小于 3500 的员工名字 
select ename from emp where sal > 2000 and sal < 3500; 
 
--并集 
select ename from emp where sal > 1000 and sal < 2500 union select ename from emp where sal > 2000 and sal < 3500; 
 
select ename from emp where sal > 1000 and sal < 2500 union all select ename from emp where sal > 2000 and sal < 3500; 
 
--交集 
select ename from emp where sal > 1000 and sal < 2500 intersect select ename from emp where sal > 2000 and sal < 3500; 
 
--减集 
select ename from emp where sal > 2000 and sal < 3500 minus 
select ename from emp where sal > 1000 and sal < 2500; 

9.2 运算符的优先级 


9.3 函数 

9.3.1 数值函数 


--数值函数 
select mod(10, 3) from dual;
select round(3.1415, 3), round(1314.1415, -2), round(1314.1415) from dual;  
select trunc(3.1415, 3), trunc(1314.1415, -2), trunc(1314.1415) from dual; --3.141 1300 1314 

9.3.2 字符型函数 


--字符型函数 
select * from emp where length(ename) > 5; --查询姓名的长度大于 5 的员工信息 
select replace('明天放假吗?真的放假吗?', '放假', '自习') from dual; --替换 
select substr('13088888888', 4, 8) from dual; --截取 

9.3.3 日期函数 


--获取当前时间 
select systimestamp from dual; 
--获取某日期的年份 
select extract(year from sysdate) from dual; 
--需求:查询 2016 入职的员工信息 
select * from emp where extract(year from hiredate) = 2016; 
--获取昨天的日期 
select sysdate - interval '1' day from dual; 
select sysdate - interval '1' month from dual; 
select systimestamp + interval '1' hour from dual; 

9.3.4 转换函数 


--转换函数 
select ename, job, to_char(hiredate, 'yyyy" 年 "MM" 月 "dd" 日 "'), to_char(sal,'$999,999,999') from emp; 
select to_date('2017/04/01', 'yyyy/MM/dd') from dual; 
select date '2017-04-01' from dual; 
select to_timestamp('2017/04/01 12:56:12', 'yyyy/MM/dd hh24:mi:ss') from dual; 
select timestamp '2017-04-01 12:56:12' from dual; 

9.3.5 其他函数 

 
--给所有入职超过 1 年的员工奖金加 300 update emp 
set comm = nvl(comm, 0) + 300 where months_between(sysdate, hiredate) >= 12; 
 
--查询员工的部门名称 
select ename, deptno, decode(deptno, '10', 'ACCOUNTING', '20', 'SALES', '其他部门') from emp; 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章