oracle入门学习总结

数据库第一天2017/9/4
主键 Primary key(PK) 主键非空切唯一
外键 Foreign Key用来关联
primary primary primary primary primary primary primary primary primary primary primary




1 数据两个管理员 sys  system


   登陆system
  (1) sqlplus
system
口令(看不到)
  (2) sqlplus system
        口令(看不到)
  (3) sqlplus system/口令(可见)


   在SQL命令行下
   (1)  conn
          system
  口令(看不到的)
   (2)  conn system
          口令(看不到)
   (3)  conn system/口令(可见)


   登陆sys
   (1)sqlplus / as sysdba
   在SQL命令行下
   (2) conn / as sysdba
  查看当前用户: show user
  退出当前用户 quit/exit




  在管理员权限下:
  创建用户:
  create user 用户名 identified by 密码;
  授权:
  grant connect,resource to 用户名;
  删除用户:
  drop user 用户名 cascade;




  导入sql文件
  1 将会话改成英文(仅在本次登陆有效)
  alter session set nls_date_language = english;
  2 导入sql文件
  @盘符:\文件名.sql;
  如: @D:\oaec.sql;




sys_guid() UUID使用方法36位的


SELECT语句
SELECT 字段名 FROM 表名


查询该用户下有哪些表
SELECT table_name FROM user_tables;


查看表结构
DESC 表名;


查询表当中所有的信息
SELECT * FROM 表名;


查询指定信息
SELECT 列名1,列名2 FROM 表名
eg:查询s_emp表下所有的员工的姓和名
SELECT first_name,last_name FROM s_emp;


算术表达式:+ - * /
操作数值类型
eg:查询所有员工的年薪
select salary*12 from s_emp;
操作日期类型(仅限加减)
eg:查询所有员工入职日期的后一天
select start_date+1 from s_emp;




NULL:进行算数运算还是NULL
需要进行空值转换
空值转换函数
NVL(列名,数值)
eg:查询所有员工的提成 没有提成的显示0
select first_name,NVL(commission_pct,0)*salary 
from s_emp;
NVL(列名,'字符串')


列的别名
跟在列名后 会默认大写
eg:将奖金取名为bonus 查询出来
select NVL(commission_pct,0)*salary bonus
from s_emp;
如果要加入特殊符号或者小写,就给别名添加"";
eg:
select NVL(commission_pct,0)*salary "Bonus"
from s_emp;


||连接符
连接之后建议区一个别名
eg:将姓和名取名为Name 查询出来
select first_name||'   '||last_name  "Name" 
from s_emp;




DISTINCT 去掉重复项
eg:查询部门表当中不重复的部门信息
SELECT DISTINCT name FROM s_dept;






ORDER BY子句
必须放在SELECT语句的最后


1)按照列名升序排序
select first_name from s_emp
order by first_name;
2)按照别名进行升序排序
select first_name "Name" from s_emp
order by "Name";
3)按照表达式进行排序
select first_name,salary*12 from s_emp
order by salary*12;
4)按照列号进行排序
select first_name,salary*12 from s_emp
order by 2;


列名后可以跟排序方式 默认是ASC(升序)
DESC(降序)


多列:
SELECT first_name,dept_id,salary
FROM s_emp
ORDER BY dept_id,salary DESC;
先按照部门ID升序排序
如果部门ID相同,就按照薪水降序排序


NULL默认为最大值




WHERE子句:条件查询


SELECT 列
FROM 表
WHERE 条件
ORDER BY..;


eg:查询薪水大于1000的员工姓名
并且按照薪水降序排序
SELECT FIRST_NAME||'  '||LAST_NAME "Name",SALARY
FROM S_EMP
WHERE SALARY>1000
ORDER BY SALARY DESC;








调整列宽
col 列名 format a字符个数;
调整数值显示位数
col 列名 format 999;(只显示三位)




WHERE子句


对字符串进行条件限制(注意使用单引号)
eg:求Ben的年薪
SELECT SALARY*12
FROM S_EMP
WHERE FIRST_NAME = 'Ben';


对日期进行限制
Oracle默认日期格式 'DD-MM-YY'
eg:求入职日期 在90年5月1日之后的所有员工
SELECT START_DATE,FIRST_NAME
FROM S_EMP
WHERE START_DATE > '01-5月-90';




WHERE子句关系运算符


BETWEEN...AND...:在。。。。和。。。之间
eg:查询薪水在1000到1500之间所有员工的姓名
SELECT FIRST_NAME
FROM S_EMP
WHERE SALARY BETWEEN 1000 AND 1500;


IN限定内容,不是区间范围
eg:查询薪水为1000和1400的员工姓名
SELECT FIRST_NAME
FROM S_EMP
WHERE SALARY IN(1000,1400);


LIKE模糊查询
通配符:
(1)% 0到多个字符 任意个字符 
(2)_ 1个字符 有且仅有一个


eg:查询名字内包含小写m的所有人
SELECT FIRST_NAME
FROM S_EMP
WHERE FIRST_NAME LIKE '%m%';


eg:查询名字第二个字母包含小写m的所有人
SELECT FIRST_NAME
FROM S_EMP
WHERE FIRST_NAME LIKE '_m%';


查询以_a开头的人的姓名
SELECT FIRST_NAME
FROM S_EMP
WHERE FIRST_NAME LIKE '\_a%' ESCAPE '\';


ESCAPE '\';   转义符
不再将'_'当作通配符来看待


IS NULL判断是否为空值
查询没有提成的员工姓名
SELECT FIRST_NAME,NVL(COMMISSION_PCT,0)
FROM S_EMP
WHERE COMMISSION_PCT IS NULL;
不可以使用 = 来判断是否为空


逻辑运算符
AND  OR  NOT


eg:查询部门id大于等于41并且薪水大于1300的员工姓名
SELECT FIRST_NAME,SALARY,DEPT_ID
FROM S_EMP
WHERE DEPT_ID >= 41
AND SALARY >1300;
eg:查询部门id大于等于41或者薪水大于1300的员工姓名
SELECT FIRST_NAME,SALARY,DEPT_ID
FROM S_EMP
WHERE DEPT_ID >= 41
OR SALARY >1300;
eg:查询部门id不等于41且薪水大于1300的员工姓名
SELECT FIRST_NAME,SALARY,DEPT_ID
FROM S_EMP
WHERE DEPT_ID NOT IN 41
AND SALARY >1300;






/*
  单行函数:
  作用在单条记录上
  每一行都可以返回一个结果
  可以嵌套
  
  1 字符函数
  UPPER 大写转换
  LOWER 小写转换
  INITCAP 首字母大写其余字母小写
  LENGTH 字符长度
  SUBSTR 字符截取 第一位是1
  NVL 空值转换
  
  查询名字长度大于5的所有员工
  SELECT FIRST_NAME
  FROM S_EMP
  WHERE LENGTH(FIRST_NAME) >= 5;
  
  一般将字符函数用于忽略大小写的比较
  
  
  数值函数
  ROUND 四舍五入
  TRUNC 截取,不进行四舍五入
  MOD   取余
  
  ROUND(数值,number)
  number:
  正整数表示保留小数点后number位
  0:取整
  负整数表示保留小数点左边几位
  
  SELECT TRUNC(15.193,-1) FROM DUAL;
  结果返回10
  DUAL是一张虚表,可以用来做一些时间查询
  或者基本的算数计算等
  
  时间函数
  查询当前时间
  SELECT SYSDATE FROM DUAL;显示的比较简单
  SELECT SYSTIMESTAMP FROM DUAL;显示的比较复杂
  
  MONTH BETWEEN 计算两个月之前的月数
  如果不是正月数,会返回小数
  SELECT months_between (SYSDATE,'10-10月-17') FROM DUAL;
  
  ADD MONTH 增加月数
  SELECT ADD_MONTHS(SYSDATE,2) FROM DUAL;
  
  NEXT_DAY 指定日期的下一天
  SELECT NEXT_DAY(SYSDATE,'星期一') FROM DUAL;
  
  LAST_DAY 指定日期所在月份的最后一天
  SELECT LAST_DAY(SYSDATE) FROM DUAL;
  
  ROUND(DATE,精确度)
  精确到年:看月份,逢七进位
  精确到月:看天数,逢16进位
  SELECT ROUND('06-9月-17','MONTH') FROM DUAL;  01-9月 -17
  SELECT ROUND('06-9月-17','YEAR') FROM DUAL;   01-1月 -18
  
  转换函数:
  TO_CHAR将日期转换为字符串
  年: YEAR,YYYY
  月: MM
  日: DD
  时: HH24
  分:  MI
  秒: SS
  fm:去掉空格和0
  SELECT TO_CHAR(SYSDATE,'fmYYYY-MM-DD HH24:MI:SS') 
  FROM DUAL;   2017-9-6 10:33:13
  
  
  SELECT LAST_NAME,TO_CHAR(START_DATE,'fmddspth "of" MONTH-YYYY-HH:MI:SS AM') HIREDATE
  FROM S_EMP
  WHERE START_DATE LIKE '%91';
  查询91年入职员工在该月份第几天入职;
  
  将数值类型转换为字符串
  SELECT TO_CHAR(12,'$0000.00') FROM DUAL;  $0012.00
  SELECT TO_CHAR(12,'L9999.99') FROM DUAL;  ¥12.00


  TO_NUMBER将字符串转化为数值
  SELECT TO_NUMBER('1')+2
  from dual;  3
  
  TO_DATE将字符串转化为日期
  可以带格式也可不带使用默认格式
  SELECT TO_DATE('06-SEP-17')+1
  FROM DUAL;
 */ 
  SELECT TO_DATE('2017-06-12 22:22:22','YYYY-MM-DD HH24:MI:SS')
  FROM DUAL;


/*
   多表查询:
   1 等价连接 表之间的连接使用“=” 
   如果不链接 就会出现笛卡儿积 造成数据的浪费
   会产生大量无意义的数据
   查询所有的员工姓名和所在部门
   SELECT FIRST_NAME,NAME
   FROM S_EMP,S_DEPT
   WHERE S_EMP.DEPT_ID = S_DEPT.ID;
   
   查询所有部门名及其所在区域
  SELECT S_DEPT.NAME,S_REGION.NAME
  FROM S_DEPT,S_REGION
  WHERE S_DEPT.REGION_ID = S_REGION.ID;


  SELECT D.NAME,R.NAME
  FROM S_DEPT D,S_REGION R
  WHERE D.REGION_ID = R.ID;
  
  多表查询,如果出现同名字段,可以使用表名.字段名来区分
  也可以使用别名,但是注意,一旦定义了别名,就必须使用。
  
  查询所有薪水大于1000的员工的姓名,薪水,属部门
  SELECT E.FIRST_NAME,E.SALARY,D.NAME
  FROM S_EMP E,S_DEPT D
  WHERE E.DEPT_ID = D.ID
  AND E.SALARY > 1000;
  查询员工的姓名,部门名,部门所在区域
  SELECT E.FIRST_NAME,D.NAME,R.NAME
  FROM S_DEPT D,S_EMP E,S_REGION R
  WHERE E.DEPT_ID = D.ID
  AND D.REGION_ID = R.ID;
  
  不等价连接
  不使用“=”进行的连接 可以是 > BETWEEN AND  LIKE 等
  
  查询所有员工姓名 职位 薪水 以及 薪水等级
  SELECT E.FIRST_NAME,E.SALARY,E.TITLE,S.GRADE
  FROM S_EMP E,S_SALGRADE S
  WHERE E.SALARY BETWEEN S.LOSAL AND S.HISAL;
  
  外连接
  查所有的客户NAME以及客户对应的销售人员NAME
  SELECT C.NAME,E.FIRST_NAME
  FROM S_CUSTOMER C,S_EMP E
  WHERE E.ID (+)= C.SALES_REP_ID;
  左外连接 写在等号右侧 显示左侧未匹配项
  右外连接 写在等号左侧 显示右侧未匹配项
  只有oracle数据库才允许使用(+)来表示左外右外连接
  其他数据库外连接标准写法
  SELECT C.NAME,E.FIRST_NAME
  FROM S_CUSTOMER C LEFT JOIN S_EMP E
  ON E.ID = C.SALES_REP_ID;
  全外连接:
  既显示没有客户的员工,也显示没有员工的客户
  SELECT C.NAME,E.FIRST_NAME
  FROM S_CUSTOMER C FULL JOIN S_EMP E
  ON E.ID = C.SALES_REP_ID;
 
  内连接 inner join 作用和等价连接相同 很少使用
  SELECT D.NAME,R.NAME
  FROM S_DEPT D inner join S_REGION R
  on D.REGION_ID = R.ID;
  
  自连接:在一张表中,自己和自己连接
  eg:查询所有员工和其领导的姓名
  SELECT W.FIRST_NAME,L.FIRST_NAME
  FROM S_EMP W,S_EMP L
  WHERE W.MANAGER_ID = L.ID(+);
*/








/*
  集合运算符
  1 union:并集 把重复的去掉 并且按照查询的第一列升序排序
  如果 134578
       union
       1364
  结果返回 1345678
  左外连接union右外连接 = 全连接
  SELECT E.FIRST_NAME,C.NAME
  FROM S_EMP E FULL JOIN S_CUSTOMER C
  ON E.ID = C.SALES_REP_ID;


  SELECT E.FIRST_NAME,C.NAME
  FROM S_EMP E LEFT JOIN S_CUSTOMER C
  ON E.ID = C.SALES_REP_ID
  UNION
  SELECT E.FIRST_NAME,C.NAME
  FROM S_EMP E RIGHT JOIN S_CUSTOMER C
  ON E.ID = C.SALES_REP_ID;
  
  UNION ALL 既不去掉重复的,也不进行排序
  SELECT E.FIRST_NAME,C.NAME
  FROM S_EMP E LEFT JOIN S_CUSTOMER C
  ON E.ID = C.SALES_REP_ID
  UNION ALL
  SELECT E.FIRST_NAME,C.NAME
  FROM S_EMP E RIGHT JOIN S_CUSTOMER C
  ON E.ID = C.SALES_REP_ID;
  
  MINUS 差操作 第一个结果集减去第二个结果集(公共部分)
  按照第一列升序排序
  
  rownum:代表行数
  查询前10条数据
  select * from s_emp
  where rownum <= 10
  查询第五条到第十条的数据
  select * from s_emp
  where rownum <= 10
  minus
  select * from s_emp
  where rownum <= 5;
  
  INTERSECT 取交集 按照第一列升序排序
  查询1-5条数据
  select * from s_emp
  where rownum <= 10
  INTERSECT
  select * from s_emp
  where rownum <= 5;
  
  组函数:作用于一组数据,返回一个结果
  常见 AVG()  MAX() MIN() SUM() COUNT()
  ALL 统计全部的
  DISTINCT 统计不重复的
  查询所有员工的 平均工资 工资和 最小工资 最大工资
  SELECT AVG(SALARY),SUM(SALARY),MIN(SALARY),MAX(SALARY)
  FROM S_EMP;
  查询字母最大的员工和最小员工的姓名
  SELECT MAX(FIRST_NAME),MIN(FIRST_NAME)
  FROM S_EMP;
  
  COUNT(字段名/*)统计次数
  COUNT(字段数) 不计算空的列,统计总数据不靠谱
  COUNT(*) 统计全部数据 包含空值
  统计有提成的员工数量
  SELECT COUNT(COMMISSION_PCT)
  FROM S_EMP;
  统计全部员工数量
  SELECT COUNT(*)
  FROM S_EMP;
  
  可以操作字符串 日期 数值类型的:MAX() MIN() COUNT()
  只能操作数值的: SUM() AVG()
*/








/*
GROUP BY 子句
以。。。分组


查询每个部门薪水最高是多少
SELECT MAX(SALARY),DEPT_ID
FROM S_EMP
GROUP BY DEPT_ID;


错误1:ORA-00979 不是 GROUP BY 表达式
SELECT语句中出现的字段必须出现在GROUP BY子句中
SELECT MAX(SALARY),FIRST_NAME
FROM S_EMP
GROUP BY DEPT_ID;




错误2 ORA-00934: 此处不允许使用分组函数
组函数不可以和WHERE子句配合使用
SELECT MAX(SALARY),DEPT_ID
FROM S_EMP
WHERE MAX(SALARY) >1000
GROUP BY DEPT_ID;


查询语句中如果有组函数,那么查询的列
要么是组函数,要么是被分组的列


HAVING子句 写在GROUP BY 子句之后
对GROUP BY子句做出限制
查询最大薪水大于1400的所有部门编号,并升序排序
SELECT MAX(SALARY),DEPT_ID
FROM S_EMP
GROUP BY DEPT_ID
HAVING MAX(SALARY) >1400
ORDER BY DEPT_ID;


执行顺序: 1.WHERE->2.GROUP BY->3.HAVING->4.ORDER BY


S_ORDER订单表
S_ITEM订单明细表
1 统计每一个订单的订单明细数量
SELECT ORD_ID,COUNT(*)
FROM S_ITEM
GROUP BY ORD_ID;
2 查询订单号对应的订单明细数量及总额
SELECT ORD_ID,COUNT(*),SUM(PRICE)
FROM S_ITEM
GROUP BY ORD_ID;


子查询:
查询部门编号是41的所有员工姓名及部门编号
SELECT FIRST_NAME,DEPT_ID
FROM S_EMP
WHERE DEPT_ID = 41;
查询LaDoris所在部门的所有员工姓名及部门编号
第一步:查询LaDoris所在的部门编号
第二步:根据查到的部门ID进行信息匹配
SELECT FIRST_NAME,DEPT_ID
FROM S_EMP
WHERE DEPT_ID = (
  SELECT DEPT_ID
  FROM S_EMP
  WHERE FIRST_NAME = 'LaDoris'
);
子查询是一个完整的select语句
外围可以跟SELECT INSERT CREATETABLE
如果外围是SELECT
子查询可以写在WHERE/HAVING/FROM


查询和Patel(last_name)同一个部门的所有人员信息及部门id
SELECT LAST_NAME,DEPT_ID
FROM S_EMP
WHERE DEPT_ID IN (
  SELECT DEPT_ID
  FROM S_EMP
  WHERE LOWER(LAST_NAME) = 'patel'
);
如果子查询就产生一个结果使用“=”
如果产生了多个结果使用关键字IN


查询薪水高于平均工资的员工姓名
SELECT FIRST_NAME,SALARY
FROM S_EMP
WHERE SALARY > (
  SELECT AVG(SALARY)
  FROM S_EMP
);
使用子查询可以解决组函数和WHERE子句不兼容的问题


子查询配合HAVING子句:
查询平均薪水大于41号部门平均薪水所有部门ID
SELECT DEPT_ID,AVG(SALARY)
FROM S_EMP
GROUP BY DEPT_ID
HAVING AVG(SALARY) > (
    SELECT AVG(SALARY)
    FROM S_EMP
    WHERE DEPT_ID =41
);
子查询配合FROM使用
查询第5到10条数据
SELECT R,FIRST_NAME
FROM (
  SELECT ROWNUM R,FIRST_NAME
  FROM S_EMP
)
WHERE R BETWEEN 5 AND 10;
主查询可以引用子查询的数据


子查询也可以引用主查询的字段
查询薪水高于其领导的所有员工姓名
方式1 使用自连接
SELECT E1.SALARY,E1.FIRST_NAME,E2.SALARY,E2.FIRST_NAME
FROM S_EMP E1,S_EMP E2
WHERE E1.MANAGER_ID = E2.ID
AND E1.SALARY > E2.SALARY;
方式二:使用子查询
SELECT SALARY,FIRST_NAME
FROM S_EMP E
WHERE E.SALARY > (
  SELECT SALARY
  FROM S_EMP
  WHERE E.MANAGER_ID = ID
);
*/






数据类型
varchar2(size)  Variable length character values可变字符串长度
char(size) Fixed length character values 固定字符串长度默认长度为1
number Floating point numbers 整形参数有两个(第一个正数的,第二个小数的长度)
date Date and time values 时间类型长度
长类型的 字符串
clob Variable length character values up to 2GB 
blob Variable length character for binary data








第六天


/*
实体:一些数据表 类似于java当中的类
属性:表中的列 类似于java当中的属性
关系:表与表之间的关系(实体之间的关系)
一对一:人和护照 外键放在任意一侧都可以
如果一侧实线一侧虚线 外键放在实线一侧
一对多:销售人员和客户 外键放到多的那一侧
多对多:老师和学生 
第一种方式:将多对多拆分为多个一对多
第二种方式:建立一张桥表,引用两个表的主键作为联合主键
间接实现两张表的连接


完整性约束:5个
主键 primary key  PK 
一张表当中只能有一个主键 非空且唯一
如果是联合主键 联合唯一,单列非空
代理主键:一般来说是数值类型 没有具体意义
代表的唯一的一行数据,推荐使用
自然主键:本身就具有意义的数据,有可能会被修改
不推荐使用


外键 foreign key FK
可以是一列,也可以是多列,值可以为空,来源于其他表的
主键列或者唯一项 ,如果外键作为联合主键存在,则不可以
为空


非空 not null


唯一 unique


自定义约束 check




DDL语句
1CREATE语句
CREATE TABLE 表名(
   列名1  数据类型(长度) 约束,
   列名2  数据类型(长度) 约束,
   列名3  数据类型(长度) 约束
);


命名规则:
以字母开头,多个单词用“_”分割
组成:字母 数字 下划线 美元符 #
不能使用系统关键字,不可以出现同名表


数据类型:
字符串:
VARVHAR2  变长字符串:varrchar2(20)
CHAR      定长字符串char(20)
数值型;
NUMBER   NUMBER(10)  NUMBER(10,2)
时间型:
DATE


CLOB:大字符串
BLOB:大二进制数据




约束:表级别约束,列级别约束
如果约束自动创建,约束名就为SYS_.....
建议给约束起名 使用关键字CONSTRAINT
默认格式最好为:表名_列名_约束简写


create table teacher(
  id number(10) CONSTRAINT TEACHER_ID_PK primary key,
  name varchar2(40) CONSTRAINT TEACHER_NAME_NN not null,
  sex varchar2(10)  CONSTRAINT TEACHAER_SEX_CK CHECK(sex in('男','女')),
  age number(20) CONSTRAINT TEACHER_AGE_CK CHECK(age < 150 AND age >0)
)
*/


drop table teacher;


/*
  学科表
  ID  学科ID
  NAME 学科名
*/
create table TEST_SUBJECT(
  ID NUMBER(10) CONSTRAINT TEST_SUBJECT_ID_PK PRIMARY KEY,
  NAME VARCHAR2(40) CONSTRAINT TEST_SUBJECT_NAME_NN NOT NULL
)
/*
  老师表
  id  主键 代表老师的id
  name 非空
  sex  限制
  age  限制
  subject_id 学科id
*/
create table teacer(
  id number(10) CONSTRAINT TEACHER_ID_PK primary key,
  name varchar2(40) CONSTRAINT TEACHER_NAME_NN not null,
  sex varchar2(10)  CONSTRAINT TEACHAER_SEX_CK CHECK(sex in('男','女')),
  age number(20) CONSTRAINT TEACHER_AGE_CK CHECK(age < 150 AND age >0),
  subject_id number(20) CONSTRAINT TEACHER_SUBJECT_ID_FK REFERENCES TEST_SUBJECT(ID)
)








drop table teacher;




/*
  学科表
  ID  学科ID
  NAME 学科名
*/


create table TEST_SUBJECT(
 
ID NUMBER(10) CONSTRAINT TEST_SUBJECT_ID_PK PRIMARY KEY,

 NAME VARCHAR2(40) CONSTRAINT TEST_SUBJECT_NAME_NN NOT NULL


)


/*
  老师表
  id  主键 代表老师的id
  name 非空
  sex  限制
  age  限制
  subject_id 学科id
*/
create table teacher(


  id number(10) CONSTRAINT TEACHER_ID_PK primary key,
 
  name varchar2(40) CONSTRAINT TEACHER_NAME_NN not null,


  sex varchar2(10)  CONSTRAINT TEACHAER_SEX_CK CHECK(sex in('男','女')),


  age number(20) CONSTRAINT TEACHER_AGE_CK CHECK(age < 150 AND age >0),


  subject_id number(20) CONSTRAINT TEACHER_SUBJECT_ID_FK REFERENCES TEST_SUBJECT(ID)


)
/*
  
约束:
  1 列级别约束
  直接定义在列名后,约束和列名之间没有逗号间隔
  2 表级别约束
  在列名定义后,约束和表通过逗号隔开的
 NOT NULL只能用于列级别,不能用于表级别,其他约束在
列级别和表级别上均可定义 约束(包括联合主键,联合外键,联合唯一键)时必须在表级别上定义
如果为两个或者两个以上的列定义联合
 */




/*
  学生表
  id  学生的学号
  name 学生的姓名
  age 年龄18~25之间
*/


/*列级别约束建表*/


CREATE TABLE STUDENT(
  
ID NUMBER(10) CONSTRAINT STUDNT_ID_PK PRIMARY KEY,

NAME VARCHAR2(20) CONSTRAINT STUDENNT_NAME_NN NOT NULL,
AGE NUMBER(10) CONSTRAINT STUDENT_AGEE_CK CHECK(age > 18 AND age <25)


)


/*表级别约束建表*/
CREATE TABLE STUDENT(


  ID NUMBER(10),


  NAME VARCHAR2(20),


  AGE NUMBER(10),


  /*主键的表级别约束*/


CONSTRAINT STUDENT_ID_PK PRIMARY KEY(ID),


/*CHECK的表级别约束*/
 
 CONSTRAINT STUDENT_AGE_CK CHECK(AGE > 18 AND AGE <25)


)






/*外键的列级别约束*/


CREATE TABLE WORKER(


  ID NUMBER(10) CONSTRAINT WORKER_ID_FK  REFERENCES TEACHER(ID)


)




/*外键的表级别约束*/


CREATE TABLE WORKER(


  ID NUMBER(10),


  CONSTRAINT WORKER_ID_FK FOREIGN KEY(ID) REFERENCES TEACHER(ID)


)






/*
  授课表
  TEACHER_ID(外键)
  STUDENT_ID(外键)
*/


CREATE TABLE TEACH(


  TEACHER_ID CONSTRAINT TEACH_TEACHER_ID_FK REFERENCES TEACHER(ID),


  STUDENT_ID CONSTRAINT TEACH_STUDENT_ID_FK REFERENCES STUDENT(ID),


  /*表级别约束定义联合主键*/


  CONSTRAINT TEACH_S#T_PK PRIMARY KEY(TEACHER_ID,STUDENT_ID)
 
)




/*查看一张表当中的所有的约束
注意表名大写
*/


as 
SELECT CONSTRAINT_NAME,
CONSTRAINT_TYPE 
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'TEACHER'
;


/*通过子查询创建表
注意:数据会被复制 但是约束只能复制NOT NULL*/


CREATE TABLE COPY_OF_TEACHER
AS
SELECT * 
FROM TEACHER;




/*ALTER语句
增加表列:
ALTER TABLE 表名
ADD (
  列名1 数据类型(长度),
  列名2 数据类型(长度),
)
约束只可以添加NOT NULL 并且是在表中没有数据的前提下
也可以添加默认值 道理同上
*/


ALTER TABLE TEACHER


ADD(
 BIRTH VARCHAR2(20) 
);






/*
  修改列
  有个关键字是modify MODIFY这个关键字
修改表列 默认格式语法:
ALTER TABLE table 
MODIFY (column datatype [DEFAULT expr][NOT NULL]
[,column datatype]...);


修改表列要注意的事:
1.修改表列的同时,可以增加not null约束以及默认值,不能增加其他约束
2.若要缩小列的宽度,只有该列值为空或表里没有记录
3.增加的默认值只能拿个影响到后来插入的值
4.若一列有空值不能加非空约束
5.若要改变列的类型只有该列为空或这表里没有记录。
ALTER TABLE 表名
  MODIFY(
    列名 数据类型
  )
*/




ALTER TABLE TEST


MODIFY(
  NAME VARCHAR2(60) DEFAULT '张三'
);




/*增加 修改 只可以添加非空约束*/




/*
关键词组 drop column
语法格式:
ALTER TABLE table 
DROP COLUMN column_name;
删除列
ALTER TABLE 表名
DROP COLUMN列名




不能直接删除有主外键关系的列


*/


ALTER TABLE TEST
DROP COLUMN NAME;








/*增加约束
ALTER TABLE table 
ADD[CONSTRAINT constraint] type (column);
NOT NULL 约束只能在增加列或者修改列的时候完成
*/


ALTER TABLE TEST


ADD CONSTRAINT TEST_ID_PK PRIMARY KEY(ID);


ALTER TABLE TEST


ADD CONSTRAINT TEST_ID_CK CHECK(ID > 20);


/*删除约束
CASCADE :级联 破坏掉字段所属的级联关系
所以,想要删除主外键关系列,就必须先破坏掉关系
才可以删除
*/




ALTER TABLE TEST 


DROP CONSTRAINT TEST_ID_PK CASCADE;




/*约束失效*/


ALTER TABLE TEST


DISABLE CONSTRAINT TEST_ID_CK CASCADE;
/*约束生效 所有数据都必须满足生效条件才可以*/
ALTER TABLE TEST
ENABLE CONSTRAINT TEST_ID_CK;


/*
  约束只可以添加 删除 生效 失效 但不可以被修改
*/








/*DROP 删除表 
DROP TABLE 表名 
表和数据都没有了


CASCADE CONSTRAINTS 级联删除相关联性约束
不能进行回滚该命令。
*/


DROP TABLE TEST;




/*TRUNCATE 截断表(清空表)
TRUNCATE TABLE 表名 
数据都没有了 表还在


删除表中所有的记录
释放表中所占用的表空间
是一DDL语句,不能回滚
不会触发触发器动作
TRUNCATE和DELETE的区别
1、TRUNCATE不可以回滚,DELETE可以回滚 2、在删除大量数据时,TRUNCATE
速度要比DELETE快.3.TRUNCATE可以释放表空间,DELETE不可以释放表空间
4.TRUNCATE操作对象只能是表,DELETE可以是表、视图或者同义词。
*/


TRUNCATE TABLE STUDENT;




/*重命名表名*/


RENAME oldname TO newname;




/*重命名列名*/


ALTER TABLE TEST_STUDENT RENAME COLUMN
ID oldname TO newname;














user_constraints


constraints_name,constraints_type
sys_开头***    C代表非空约束
sys_******* P代表主键约束
sys_******* U代表唯一约束
sys_******* R代表外键约束


级联删除
在references 外键 后面加上 on delete cascade


使用子查询创建表
creater table table
[column(,column...)]
as subquery;
通过子查询创建表,可以获得源表的结构以及数据
只有not null约束才能拷贝如新表其他约束丢失




留给第七天上午的






/*
DML语句 对表的数据产生影响
INSERT DELETE UPDATE
INSERT语法格式:
INSERT INTO TABLE [COLUMN,[COLUMN..]]
VALUES(VALUE[,VALUE...]);
例子:
INSERT插入一条数据
INSERT INTO 表名(列1,列2)
VALUES (值1,值2);
如果不指定列名,就必须按照顺序插入所有的值
注意外键可以为空
*/


一次插入一行记录
列名和插入值的顺序、类型和数量的一致




INSERT INTO TEACHER(name,id)
VALUES ('王五',4);


/*使用子查询一次性插入多条数据*/
INSERT INTO TABLE [(COLUMN[,COLUMN..])] SUBQUERY
一次插入多行记录 
通过子查询实现批量插入
列名和插入值顺序、类型和数量一致
INSERT INTO TEACHER(ID,NAME)
SELECT ID,FIRST_NAME
FROM S_EMP;


/*
  UPDATE
  UPDATE 表名
  SET 列1 = 值1,列2 = 值2
  WHERE.....;
  修改Ben的NAME为Jack
*/
UPDATE TEACHER
SET NAME = 'Ben',sex = '男'
WHERE NAME = 'Jack';


/*
 DELETE
 DELETE FROM 表名
 WEHRE 条件;
 如果没有条件就会删除所有记录
*/
DELETE FROM TEACHER
WHERE ID = 1;


/*
  TRUNCATE 与 DELETE的区别
  1 truncate DDL语句  delete是DML语句
  DDL语句是不可逆的  DML是可逆的
  2 truncate会释放表空间 delete不会释放
   truncate适合删除大量表中数据
  3 truncate只可以作用于表
    delete可以作用于 表 同义词 视图
  
  
  如果存在主外键关系
  我们必须先删子表,再删主表
*/








/*
  事务 ACID
  
  COMMIT正常提交事务
  DDL/DCL:自动调用COMMIT
  DML:不会自动提交COMMIT
  
  ROLLBACK回滚 回滚到事务的开始点
  try{
    1 插入了一个subject
    2 插入了一个老师 对应新插入的subject
    commit
  }catch(e){
    rollback
  }
  代码都执行成功了才commit,否则就rollback
*/


/*设置回退节点*/
INSERT INTO SUBJECT
VALUES (2,'WEB');
SAVEPOINT S;
INSERT INTO SUBJECT
VALUES (3,'ORACLE');
ROLLBACK TO S;


/*
  数据字典
  1 user_table:查看所有表
  2 user_constrants :查看所有约束
  3 USER_CONS_COLUMNS:查看约束对应的列
  4 USER_USERS:查看当前用户信息
  views视图  indexes索引  sequences序列
*/
select *
from USER_USERS;




/*
  序列 4是ORACLE特有的对象,能够产生连续的整数值
  用来生成主键
*/


CREATE SEQUENCE TEACHER_SEQ1


起始值
STARTWITH 1


--步长一次增加几个字节
INCREMENT BY 1


--最大值
MAXVALUE 999999


--没有缓冲区
NOCACHE


--没有循环
NOCYCLE;


/*
  调用序列的下一个值 NEXTVAL
*/


SELECT TEACHER_SEQ.NEXTVAL FROM DUAL;


/*
 序列的当前值 CURRVAL
  没有初始化的序列无法调用当前值
*/


SELECT TEACHER_SEQ.CURRVAL FROM DUAL;
INSERT INTO TEACHER


VALUES(TEACHER_SEQ.NEXTVAL,'JACK','BOY',1);


/*
  序列的数据字典 user_sequences
*/


SELECT * FROM user_sequences;


/*
  删除序列
  DROP SEQUENCE 序列名
*/


DROP SEQUENCE TEACHER_SEQ1;


/*
  修改序列
  ALTER SEQUENCE 序列名
  .....
  不可以修改起始值
*/


ALTER SEQUENCE TEACHER_SEQ


INCREMENT BY 2


MAXVALUE 123456


CYCLE


CACHE 10;


/*
  视图VIEW
  视图本质上就是一个带有名字的select语句
 
 一般用户无法直接创建视图
  需要DBA授权 GRANT CREATE VIEW TO 用户名
*/


CREATE VIEW DEPT_41


AS SELECT ID,
FIRST_NAME,DEPT_ID


FROM S_EMP


WHERE DEPT_ID = 41;


/*利用视图获取41号部门的相关信息*/


SELECT FIRST_NAME
FROM DEpt_41;


/*
  OR REPLACE如果有相同的视图就替换掉
*/


CREATE OR REPLACE VIEW DEPT_41
AS SELECT ID,FIRST_NAME,DEPT_ID,SALARY
FROM S_EMP
WHERE DEPT_ID = 41;


/*给视图列起名字*/


CREATE OR REPLACE VIEW DEPT_41
(ID,NAME,D_ID,MONEY)


AS SELECT ID,FIRST_NAME,DEPT_ID,SALARY
FROM S_EMP


WHERE DEPT_ID = 41;


/*
创建一个视图
要求显示
教java的所有老师的 NAME SEX SUBJECT_ID
*/






















/*
  序列 SEQUENCE
  是ORACLE特有的对象,能够产生连续的整数值
  用来生成主键
*/
CREATE SEQUENCE TEACHER_SEQ1
START WITH 1
INCREMENT BY 1
MAXVALUE 999999
NOCACHE
NOCYCLE;
/*
  调用序列的下一个值 NEXTVAL
*/
SELECT TEACHER_SEQ.NEXTVAL FROM DUAL;
INSERT INTO TEACHER
VALUES(TEACHER_SEQ.NEXTVAL,'JACK','BOY',1);
/*
  序列的数据字典 user_sequences
*/
SELECT * FROM user_sequences;
/*
  序列的当前值 CURRVAL
  没有初始化的序列无法调用当前值
*/
SELECT TEACHER_SEQ.CURRVAL FROM DUAL;
/*
  删除序列
  DROP SEQUENCE 序列名
*/
DROP SEQUENCE TEACHER_SEQ1;
/*
  修改序列
  ALTER SEQUENCE 序列名
  .....
  不可以修改起始值
*/
ALTER SEQUENCE TEACHER_SEQ
INCREMENT BY 2
MAXVALUE 123456
CYCLE
CACHE 10;
/*
  视图VIEW
  视图本质上就是一个带有名字的select语句
  一般用户无法直接创建视图
  需要DBA授权 GRANT CREATE VIEW TO 用户名
*/
CREATE VIEW DEPT_41
AS SELECT ID,FIRST_NAME,DEPT_ID
FROM S_EMP
WHERE DEPT_ID = 41;
/*利用视图获取41号部门的相关信息*/
SELECT FIRST_NAME
FROM DEpt_41;
/*
  OR REPLACE如果有相同的视图就替换掉
*/
CREATE OR REPLACE VIEW DEPT_41
AS SELECT ID,FIRST_NAME,DEPT_ID,SALARY
FROM S_EMP
WHERE DEPT_ID = 41;
/*给视图列起名字*/
CREATE OR REPLACE VIEW DEPT_41
(ID,NAME,D_ID,MONEY)
AS SELECT ID,FIRST_NAME,DEPT_ID,SALARY
FROM S_EMP
WHERE DEPT_ID = 41;
/*
创建一个视图
要求显示
教java的所有老师的 NAME SEX SUBJECT_ID
*/
CREATE VIEW TEACHER_MESSAGE
AS
SELECT NAME,SEX,SUBJECT_ID
FROM TEACHER
WHERE SUBJECT_ID = 1;
/*
  对视图使用DML语句
  其实就是在对表使用DML语句
  修改表的数据,所对应的视图也会发生变化
*/
UPDATE TEACHER_MESSAGE
SET NAME = 'FRANK';






CREATE OR REPLACE VIEW TEACHER_MESSAGE
AS
SELECT ID,NAME,SEX,SUBJECT_ID
FROM TEACHER
WHERE SUBJECT_ID = 1
WITH READ ONLY;
/*
  WITH READ ONLY只读,一旦定义就只能被查看,不能修改
*/
INSERT INTO TEACHER_MESSAGE
VALUES(TEACHER_SEQ.NEXTVAL,'LUCY','GIR',1);








CREATE OR REPLACE VIEW TEACHER_MESSAGE
AS
SELECT ID,NAME,SEX,SUBJECT_ID
FROM TEACHER
WHERE SUBJECT_ID = 1
WITH CHECK OPTION;
/*WITH CHECK OPTION 可以增删改
但是必须满足where条件
*/
INSERT INTO TEACHER_MESSAGE
VALUES(TEACHER_SEQ.NEXTVAL,'ABCD','GIR',2);/*错*/
INSERT INTO TEACHER_MESSAGE
VALUES(TEACHER_SEQ.NEXTVAL,'ABCD','GIR',1);/*对*/


/*复杂视图:数据来源于多个表
不可以同时增删改两个表中的数据
*/
CREATE VIEW MESSAGE
AS
SELECT E.FIRST_NAME,D.NAME 
FROM S_EMP E,S_DEPT D
WHERE E.DEPT_ID = D.ID;
/*
删除视图 DROP VIEW 视图名
*/
DROP VIEW MESSAGE;
/*
视图对应的数据字典:user_views
*/
SELECT *
FROM USER_VIEWS;




/*
INDEX索引
加快数据库检索速度
一些表数据量比较大,但是要查找的值只占其中的很小一部分
大概5%左右,可以创建索引,提高查询效率


主键,唯一项会自动创建索引
*/
CREATE INDEX TEACHER_NAME_IDX
ON TEACHER(NAME);
/*删除索引*/
DROP INDEX TEACHER_NAME_IDX;




/*
  临时表空间:负责执行算法的临时空间
  每次数据库关闭都会清空临时表空间
  
  表空间:数据库的存储空间,会一直存在,
  不会自动丢失。
  
  oracle有默认的表空间system
  和临时表空间users
*/
/*表空间的创建*/
CREATE TABLESPACE OAECSPCAE
DATAFILE 'D:\OAECSPACE.DBF'
SIZE 500M
AUTOEXTEND ON NEXT 5M MAXSIZE 1000M
EXTENT MANAGEMENT LOCAL;


/*临时表空间的创建*/
CREATE TEMPORARY TABLESPACE OAEC_TEMPS
TEMPFILE 'E:\OAEC_TEMPS.DBF'
SIZE 50M
AUTOEXTEND ON NEXT 5M MAXSIZE 100M
EXTENT MANAGEMENT LOCAL;


/*使用自定义表空间和临时表空间创建用户*/
CREATE USER SSSS IDENTIFIED BY SSSS
DEFAULT TABLESPACE OAECSPACE
TEMPORARY TABLESPACE OAEC_TEMPS;


/*DBA授权:在DBA权限下*/
GRANT DBA TO TESTS;
/*撤销权限*/
REVOKE DBA FROM tests;


/*创建同义词*/
CREATE SYNONYM UU
FOR S_EMP;


/*数据泵导出数据*/
$exp userid=tests/tests full=y file=D:\ss.dmp;
/*数据泵导入数据*/
$imp userid=SSSS/SSSS full=y file=D:\ss.dmp;




视图view


--创建视图的方法
create view course_view
as select id,name,credit
from course;
--带where条件的,视图名字不能重复
create view course_view2
as select id,name,credit
from course
where credit = 50;
select * from course_view;


create or replace view course_view2
--or replace 创建或者替换
--这个是给对应的列起别名 
(newid,newname,newcredit)
as select id,name,credit
from course
where id = 3;
select * from course_view2;


create or replace view course_view2
as select * from course
where id between 2 and 3
--这个的作用就是向视图中插入的数据必须符合where条件
with check option;


create or replace view course_view3
as select * from course
--只读这个不能让视图被修改,但是修改源表依然会改变视图
with read only;


--复杂视图,多个表直接的连接
create view dept_sum_vn
(name,minsal,maxsal,avgsal)
as select d.name,MIN(e.salary),
max(e.salary),avg(e.salary)
from s_emp e,s_dept d
where e.dept_id = d.id
group by d.name;


select * from dept_sum_vn;


--删除视图
drop view dept_sum_vn;


select * from dept_sum_vn;






数据库权限
创建用户
create user scott(用户名) identified by tiger(密码)


创建用户不是用表空间


CREATE USER oace IDENIFIED BY oaec
--指定默认表空间
DEFAULT TABLESPACE oaecspace
--使用临时表空间
TEMPORARY TABLESPACE oaec_temp;


修改用户密码
ALTER USER scott IDENTIFIED BY lion;


角色


connect:提供了登录和执行基本函数的能力。可以连接数据库以及在这
些表中对数据进行查询,插入,修改及删除的权限。


resource:建立对象的能力


dba:拥有所有的系统权限,包括无线的空间配额,以及给其他用户授予
全部权限的能力。


select sydate from dual;返回当前的日期函数












--权限
--权限授予用户对象权限
GRANT object priy[(columns)]
ON  object
TO {user|role|PUBLIC}
--允许分配到权限的用户继续将权限分配给其他用户
[WITH GRANT OPTION]
--PUBLTC:将权限赋予给所有的用户
--WITH GRANT OPTION:权限的授权者也可以将权限赋予其他的用户
--没有这个选项,接受权限用户就不能将接受到的权限在赋予其他的用户,此选项不能赋予PUBLTC


--将查询表emp的权限赋予给sue和rich用户
GRANT SELECT 
ON s_emp
TO sue,rich;


--将修改表s_dept中的id,name,region_id的权限赋予给scott,manager
GRANT UPDATE(id,name,region_id)
ON s_dept
TO scott,manager;


--将查询表s_emp的权限赋予给scott,并且他还有这个向下赋予的权限。
GRANT select 
ON S_EMP
TO scott
WITH GRANT OPTION;


--回收权限
REVOKE select,insert
ON s_dept
FROM scott;
--WITH GRANT OPTION:回收 赋予给其他用户的权限


--同义词synonym 为对象定义另一个名字,可以通过这个名字访问该对象
CREATE [PUBLIC] SYNONYM synonym_name FOR object_name;
--PUBLITC:创建和删除同义词只能由DBA执行
--删除同义词
DROP SYNONYM synonym_name;
--注意在导入导出之前要注意回话格式,并且数据还得在cmd中断开连接的情况下导出
alter session set nls_date_language = english;
--数据导出
 exp userid=oace2/oace2 full=y file=E:/oace2.dmp;


--数据导入
 imp userid =oaec2/oace2 full=y file=sql.dmp;






创建索引
create index s_emp_last_name_idx
on s_emp(last_name);


确定索引
user_indexes包含索引的名字和他的唯一性约束索引
user_ind_columns包含索引名、表名和列名。




Oracle 体系结构
表空间是Oracle数据库最大的逻辑结构,一个Oracle数据库在逻辑上由多个表空间组成,
一个表空间只隶属于一个数据库。
Oracle中有一个称为SYSTEM的表空间,这个表空间是在创建或安装数据库时自动创建的
。主要用于存储系统的数据字典,过程,函数,触发器等;也可以储存用户的表,索引等。
表空间在物理上包含一个或多个数据文件。
查看表空间
--defaul_tablespace是默认表空间,temporaru_tablespace临时表空间。
select username,user_id,default_tablespace,temporary_tablespace
from dba_user;


创建表空间
create tablespace oaecspace
datafile 'src.dbf'
size 500m
autoextend no next 5m maxsize 1000m
extent management local;




创建临时表空间
create temporary tablespace oace_temp
tempfle 'src.dbf'
size 32M
--这里代表自动正将
autoextend on next 32M maxsize 512m
extent management local;


扩展表空间之方法1:
修改数据库的数据文件system.dbf,扩展其大小为1024m
alter database datafile  'src' 
resize 1024m;


扩展表空间之方法2:
修改数据库的数据文件system.dbf,其大小每次自动扩展100m,最大为1000m
alter database datafile 'src'
autoextend on 
next 100m
maxsize 2048m;


删除表空间
drop tablespace oaecspace
including contents and datafiles;




oacle数据库文件名字: ojdbc6.jar


JDBC驱动类型
1、jdbc-odbc桥加odbc
将jdbc调用转换为odbc调用,性能低
2、本地api部分用java编写的驱动
将jdbc调用转换为RDBMS调用,要在客户端安装相关的数据库客户端程序。
JDBC驱动由两部分组成,一部分用Java编写,一部分
是其他语言编写的二进制代码。
3、基于网络纯Java的驱动
将jdbc调用转换为与dbms无关的网络协议,然后由
相应服务器转换为dbms调用。
4、基于本地协议纯Java的驱动
将jdbc嗲用后直接和数据库进行交互。


JDBC的常用的API
Driver:数据库驱动的借口
DriverManager:管理多个加载的驱动程序
Connection:事和数据库连接的对象形式,代表了一个和数据库的连接。
Statement:用以执行SQL语句
PreparedStatement:Statement的子接口
CallableStatement:Statement的子接口
ResultSet:封装Select语句执行返回的结果集,并提供方法对结果集中内荣进行获取和其他操作。


JDBC开发流程
1、注册驱动
使用类装载器(最常用)
Class.forName(driverName)
直接实例化驱动
Driver driver = new oracle.jdbc.driver.OracleDriver();
DriverManager.registerDriver(driver);
使用jdbc.drivers属性
java-Djdbc.drivers = driverName[:driverName1]...[:driverNamen]
常见驱动
Oracle:oracle.jdbc.driver.OracleDriver
Mysql:com.mysql.jdbc.Driver


2.建立和数据库的连接
DriverManager.getConnection()方法
getConnection(String url)
getConnection(String url,java.util.properties info)
getConnection(String url,String user String passwd)
--内部调用Driver.connect(String url,Properties info)
常见数据库URL
host 和localhost 和 127.0.0.1都可以是服务器的默认地址
Oracle jdbc:oracle:thin:@host:1521:SID
Mysql  jdbc:mesql://host:3306:SID

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章