Oracle:
数据库相关知识:
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。数据库通常分为层次式数据库、网络式数据库和关系式数据库三种;不同的数据库是按不同的数据结构来联系和组织的。将反映和实现数据联系的方法称为数据模型。层次结构模型实质上是一种有根结点的定向有序树,按照层次模型建立的数据库系统称为层次模型数据库系统;按照网状数据结构建立的数据库系统称为网状数据库系统;关系式数据结构把一些复杂的数据结构归结为简单的二元关系(即二维表格形式),由关系数据结构组成的数据库系统被称为关系数据库系统。
数据库管理系统(Database Management System)是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,简称DBMS。它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。用户通过DBMS访问数据库中的数据。数据库管理系统是数据库系统的核心,是管理数据库的软件。
Oracle数据库则为当前最主流的数据库之一,与之还有MysqL,db2,sqlserver等。
Oracle服务:
Oracle * VSS Writer Service-- Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Service)能够让存储基础设备(比如磁盘,阵列等)创建高保真的时间点映像,即映射拷贝(shadow copy)。它可以在多卷或者单个卷上创建映射拷贝,同时不会影响到系统的系统能。(非必须启动)
OracleDBConsole*-- Oracle数据库控制台服务;在运行Enterprise Manager(企业管理器EM)的时候,需要启动这个服务;此服务被默认设置为自动开机启动的(非必须启动)
OracleJobScheduler*-- Oracle作业调度服务。此服务被默认设置为禁用状态(非必须启动)
OracleMTSRecoveryService-- 服务端控制。该服务允许数据库充当一个微软事务服务器MTS、COM/COM+对象和分布式环境下的事务的资源管理器。恢复、闪回需要开启该服务(非必须启动)
OracleOraDb11g_home1ClrAgent-- Oracle数据库.NET扩展服务的一部分。 (非必须启动)
OracleOraDb11g_home1TNSListener-- 监听器服务,服务只有在数据库需要远程访问或使用sql Developer等工具的时候才需要,此服务被默认的设置为开机启动(非必须启动)
OracleService*-- 数据库服务,是Oracle核心服务该服务,是数据库启动的基础, 只有该服务启动,Oracle数据库才能正常操作。此服务被默认的设置为开机启动。(必须启动)
在cmd的运行界面上输出sqlplus和用户名scott密码tiger。出现界面即可表示oracle安装启动成功。
实现jdbc连接oracle数据库
UTILS: package oracl.example.util; import java.sql.Connection; import java.sql.DriverManager; public class Utils { public static Connection getConnection() throws Exception{ String driver = "oracle.jdbc.OracleDriver"; String url = "jdbc:oracle:thin:@localhost:1521:orcl"; Class.forName(driver); Connection conn = DriverManager.getConnection(url,"itcast","itcast"); return conn; } } Demo: package oracl.example.demo; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import oracl.example.util.Utils; public class demo1 { public static void main(String[] args) throws Exception { String sql = "select * from emp"; Connection conn = Utils.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); while(rs.next()){ System.out.println(rs.getInt("empno")); System.out.println(rs.getString("ename")); System.out.println(rs.getString("sal")); } } }
sql的相关设置语句
- 设置每行显示的最长字符数
set linesize 120
-- 设置一页显示的行数
set pagesize 20
-- 设置是否显示一页的记录数
set Feedback on/off
-- 打开或取消oracle自带的输出方法dbms_output,并输出内容
set serveroutput on/off
-- 格式化列的内容:将列名对应的列的值格式化为四位数值长度
col 表中对应的列名 for 9999
column 表中对应的列名 format 9999
【示例】
-- 表明将empno列名对应的列值格式为4位长度的数值型
col empno for 9999
-- 格式化列的内容:将列名对应的列的值格式化为10位字母长度
col 表中对应的列名 for a10
【示例】
-- 表明将ename列名对应的列值格式为10位长度的字符型
col ename for a10
定义一个表结构和数据,以及定义相关的约束条件DDL数据定义语言
/* 格式: create table <表名> ( 字段名 数据类型 [not null] [primary key],字段名 数据类型,.... constraint <约束名> check (<字段名> in (值,值)),constraint <约束名> unique(<字段名>),constraint <约束名> foreign key(<该表的外键字段>) references 外键表名(主键) 注意事项: 1.不要使用大括号{} 2.最后一个字段不要有逗号(,) ); 1.主键约束 2.检测约束 check,只允许输入指定的值 3.唯一约束 unique,设置为唯一约束的字段,相同的值只能出现一次 4.外键约束 foreign key,--用于约束数据的完整性,如果一个表与另一个表有主外键关系。外键表的数据不删除,主键外记录不能删除 5.非空约束 */ create table tb_user( user_id number(10) not null primary key,user_name varchar2(50),user_sex char(2),--类型ID user_type_id number(10) not null,--表示user_sex只能是男或女 constraint ck_user_sex check (user_sex in ('男','女')),--唯一约束 constraint uni_user_name unique(user_name),constraint fk_user_type_id foreign key(user_type_id) references tb_user_type(user_type_id) ); --查看表 select table_name from tabs; --删除表 drop table tb_user; drop table tb_user_type; --修改表 --修改表的字段属性 --增加字段 --格式: alter table <表名> add (<字段名> <数据类型> [not null][,<字段名> <数据类型> [not null]]...); alter table tb_user add(user_statuts char(2)); --修改字段 --格式: alter table <表名> modify (<字段名> <数据类型> [not null]); alter table tb_user modify (user_statuts char(2) not null); --删除字段 --格式: alter table <表名> drop (<字段名>[,字段名]); alter table tb_user drop (USER_STATUTS,USER_SEX); --修改字段名 --格式:alter talbe <表名> rename column <旧字段名> to <新字段名>; alter table tb_user rename column user_name to uname; --查看表结构 desc tb_user;
Oracle数据类型:
数据类型 |
描述 |
VARCHAR2(size) |
可变长度的字符串,其最大长度为size个字节;size的最大值是4000,而最小值是1;你必须指定一个VARCHAR2的size; |
NVARCHAR2(size) |
文字母认为是2个字节,中文2个字节 |
NUMBER(p,s) |
精度为p并且数值范围为s的数值;精度p的范围从1到38;数值范围s的范围是从-84到127; |
DATE |
有效日期范围从公元前4712年1月1日到公元后9999年12月31日 |
timestamp |
支持日期加时间,如:‘2016-08-18 12:02:01’ |
CHAR(size) |
固定长度的字符数据,其长度为size个字节;size的最大值是2000字节,而最小值和默认值是1; |
NCHAR(size) |
也是固定长度。根据Unicode标准定义 |
CLOB |
一个字符大型对象,可容纳单字节的字符;不支持宽度不等的字符集;最大为4G字节 |
NCLOB |
不支持宽度不等的字符集;最大为4G字节;储存国家字符集 |
BLOB |
一个二进制大型对象;最大4G字节 |
DML数据操作语言
Dml是对数据库里面的数据表和数据进行操作的语言
--复制表,并且包括表里面的数据有数据的 create table emp_info as select * from emp; --复制只需要一个表的结构,不要数据的 create table emp_info_nodata as select * from emp where 1=2; select * from emp_info_nodata; --增加 insert into emp(empno,ename,sal,comm,deptno) values('5','赵六',9000,20000,10); --复制一个表的数据对另一个表 insert into emp_info_nodata select * from emp; --删除 delete from emp_info_nodata where empno=1; --删除全部数据 delete from emp_info_nodata; --截断表,一次清除所有数据。等同delete from emp_info_nodata,但效率高 truncate table emp_info_nodata; --更新 update emp set ename='小李' where ename='赵六'; --查询 --单表查询 select * from emp; --连表查询 --内连接:两表个都有对应的数据才查询出来 --需求:内连接查询部门表dept,员工表emp,关联字段deptno --结果,出现的结果不包话,emp的部门编号为null记录,以及部门表为40的记录 select * from emp e inner join dept d on e.deptno=d.deptno; --等值查询,等同于内连接 select * from emp e,dept d where e.deptno=d.deptno; --外连接 --左外连接:显示左表的所有数据,如果右没有对应的记录使用null表示 select * from emp e left outer join dept d on e.deptno=d.deptno; --右外连接 select * from emp e right join dept d on e.deptno=d.deptno; ----连接查询oracle的有特殊写法 --等同与右外连接,以条件没有(+)表为基准表,连接的另外一个表没有对应记录就为null select * from emp e,dept d where e.deptno(+)=d.deptno; --等同与左外连接 select * from emp e,dept d where e.deptno=d.deptno(+); --自连接,特殊的连接查询:连接的两个表就是相同的连接查询就是自连接 --需求:查询每个员工的上司的名字 select a.*,b.ename as 上司的名字 from emp a,emp b where a.mgr=b.empno; --需求:查询部门的平均工资,最大工资,最少工资,部门人数 --聚合函数 --max --min --avg --count select deptno,max(sal),min(sal),avg(sal),count(empno) from emp group by deptno; --需求:查询部门的平均工资,最大工资,最少工资,部门人数,并且平均工资3000以上的记录。 select deptno,count(empno) from emp group by deptno having avg(sal)>3000; --关键字的优先级别 --from >where>group by>having>select>order by --需求:查询部门的平均工资,最大工资,最少工资,部门人数,并且平均工资3000以上的记录。平均工资升序
伪表dual
Dual表是一个虚拟表,用于构成select的语法规则,oracle保证了在dual里面永远只有一条记录是唯一的。
Dual的练习:
---伪表 --oracle里面,查询任何东西都是使用select关键字的, --但是,select的语法格式为 select <返回结果> from 表; --有这样的情况,有时间查询的结果是一些关键字或函数。缺少查询表。这个时候oracle使用一个临时表来 --存储这些记录,这个临时就是我们所说的伪表,dual --查询系统时间 select sysdate from dual; --运算的结果 select 9+4,9-1,9*9 from dual; --查询当前用户名 select user from dual;
伪列rowid:
Rowid是物理结构上的,在每条记录insert到数据库中时,会有一个唯一的物理记录,rowid在不同查询中是唯一的,同一条记录的rowid是相同的。
--伪列,rowid --oracle数据库在创建记录的时候,就会为每一条记录生成一个唯一标识的字段,这个字段就是rowid --解决了什么问题:就是一个表没有主键的时候。就可以使用它来找到对应的记录 select rowid,emp.* from emp where rowid='AAAR3sAAEAAAACXAAb';
伪列rownum:
Rownum是根据sql查询出的结果给每行分配一个逻辑编号;每次的查询都会有不同的编号,编号是从1开始的。
--伪列rownum --oracle在查询的时候,会给每一条记录加上一个序号,(每次查询rownum都是1开始),这个序号就是伪列rownum --作用,因为oracle不支持MysqL分页的关键字 lmint 0,3;它是使用rownum来分页的 select rownum,emp.* from emp; --需求,查询第5-10条的记录 --rownum不能使用大于或大于等于号 select rownum as r,emp.* from emp where rownum <=10 ; select * from (select rownum as r,emp.* from emp where rownum <=10) where r>=5; --排序问题,因为select的优秀级别高于order by所以出现rownum排序后就乱了。 select rownum as r,emp.* from emp order by deptno; --解决方案,先排序后查询。只能用子查询 select rownum,tmp.* from (select * from emp order by deptno) tmp; --需求,将员工按部门排序,再分页查询,取第5到10条的记录 select * from emp order by deptno; select rownum as r,tmp.* from (select * from emp order by deptno) tmp; --分页第一步,先取上限 select * from (select rownum as r,tmp.* from (select * from emp order by deptno) tmp) ee where ee.r<=10; --分页第二步,再取下限 select * from (select rownum as r,tmp.* from (select * from emp order by deptno) tmp) ee where ee.r<=10 and r>=5 ;
运算符:
运算符中分为算术运算符,逻辑运算符,集合运算符,比较运算符,连接运算符。
--运算符 --算术运算符 /* + - * / */ select 9+4,9-4,9/4,9*4 from dual; select * from emp where sal <=300*5; --对比运算符 /* = <> != < > <= >= between and is [not] null like in <> 标准的sql语法,所有数据库必须支持 !=,非标准的不等号 */ --需求,查询员工工资在2000至4000这个范围的员工,包括2000和4000 select * from emp where sal between 2000 and 4000; --需求:查询入职时间,在1981-01-01年至1982-01-01年的员工 select * from emp where hiredate between to_date('1981-01-01','yyyy-MM-dd') and to_date('1982-12-01','yyyy-MM-dd'); --需求:查询员工的资金不为空 select * from emp where comm is not null and comm <>0; --需求:员工名字有A select * from emp where ename like '%A%'; --需求:in,查询部门编号为10,20,30的员工 select * from emp where deptno in (10,30); --逻辑运算符 --and --or --not --集合运算符 /* union(并集无重复) union all(并集有重复) intersect(交集,共有部分) minus(减集,第一个查询具有,第二个查询不具有的数据) */ --需求:取员工工资1000-3000 并集 2000-5000的员工信息 --分析:1000-5000; select * from emp where sal between 1000 and 3000 union select * from emp where sal between 2000 and 5000; --需求:取员工工资1000-3000 并集 2000-5000的员工信息,有重复 --分析,1000-5000,重复范围:2000-3000 select * from (select * from emp where sal between 1000 and 3000 union all select * from emp where sal between 2000 and 5000) order by sal; --交集 --需求:取员工工资1000-3000 交集 2000-5000的员工信息 --范围:2000-3000的员工 select * from emp where sal between 1000 and 3000 intersect select * from emp where sal between 2000 and 5000; --减集 --需求:取员工工资1000-3000 为A集以及 工资2000-5000为B集的员工信息,求A集的减集 --分析:1000-1999.将A集减去交集范围的员工 select * from emp where sal between 1000 and 3000 minus select * from emp where sal between 2000 and 5000; --除非迫不得以,尽量不要使用集合运算符。 --字符串拼接运算符 ||,等同java里面的+ --需求:查询员工名字为SCOTT的用户,输出的结果为,这个员工的编号是:编号,工资:工资,名字:名字 --作用:写储存过程时,用于输出参数 select '这个员工的编号是:'||empno||',工资:'||sal||',名字:'||ename from emp where ename='SCOTT';
运算符的优先级别:
优先级 |
运算符 |
1 |
算术运算符 |
2 |
连接符 |
3 |
比较符 |
4 |
IS[NOT]NULL,LIKE,[NOT]IN |
5 |
[NOT] BETWEEN |
6 |
NOT |
7 |
AND |
8 |
OR |