魔乐在线Oracle笔记超经典_第1页
魔乐在线Oracle笔记超经典_第2页
魔乐在线Oracle笔记超经典_第3页
魔乐在线Oracle笔记超经典_第4页
魔乐在线Oracle笔记超经典_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、图表 1多表查询的基本语法查一张以上的表,就叫做多表查询例子:查询出雇员名称,部门名称和部门所在地的(一般多表查询要用别名)统计记录数:查询emp有多少条纪录左右连接(重点)select e.empno,e.ename,d.deptno,d.dname,d.locfromemp e,dept d where e.deptno=d.deptno;部门一共四个,这里只查询出三个,因为在雇员表中没有指定40部门的雇员,所以在消除笛卡尔乘机的时候没有条件符合40,如果喜欢40部门显示出来,就要用左右连接了。select e.empno,e.ename,d.deptno,d.dname,d.locfro

2、memp e,dept d where e.deptno(+)=d.deptno;(+)在左边,表示以右边的表为准,表示右链接。40部门出来了,所以此时就用到了有连接,证明以下规律(+)在左表示右连接(+)在右表示左连接.SQL:1999对SQL的支持(了解)范例:交叉连接(cross join)产生笛卡尔积select * from empt CROSS JOIN dept;查询结果 产生笛卡尔积CREATE TABLE EMP10 AS SELECT * FROM EMP WHERE DEPTNO=10;select * from emp NATURAL JOIN dept; 自动进行匹配

3、范例:USING子句,直接关联的操作列select * from emp e JOIN dept d USING (deptno) where deptno=30;把两张表的详细信息进行打印输出范例:ON子句 自己编写连接条件select * from emp e JOIN dept d ON (e.deptno=d.deptno) where e.deptno=30;范例:左连接(左外连接)右连接(右外连接)LEFT JOIN RIGHT JOIN组函数和分组统计(重点)组函数在SQL常用组函数有如下几个:COUNT()求全部记录数MAX()求最大记录数MIN()求最小记录数AVG()平均S

4、UM()求和分组统计GROUP BYselect deptno,COUNT(empno) from emp GROUP BY deptno;算出部门表的平均工资:select AVG(sal) from emp ;算出每个部门的平均工资:Select deptno,AVG(sal) from emp ; 之所以会出现这个错误是因为数据库不知道怎样在结果集中处理deptno列。考虑一下:这个查询既试图使用AVG聚合函数对多 行记录进行操作,却又试图从每行中获得deptno列的值;这两个操作是不可能同时完成的。此时必须提供一个GROUP BY子句告诉数据库将deptno列相同的行分组在一

5、起,然后数据库就可以将这些组中的行传递给AVG函数。警告:如果查询中包含聚合函数,而所选择的列并不在聚合函数中,那么这些列就必须在GROUP BY子句中。按部门分组,并显示部门名称,以及部门员工数select d.dname,count(e.empno) from dept d,emp ewhere d.deptno=e.deptno GROUP BY d.dname;要求查出平均工资大于2000的部门编号和平均工资select deptno,AVG(sal) from emp WHERE AVG(sal) >2000 GROUP BY deptno; 之所以会出现这个错误是因

6、为WHERE子句只能用来对单行而不是行组进行过滤。要过滤行组,可以使用HAVING子句。范例:显示非销售人员工作名称以及从事同一工作雇员的月工资的总和,并且要满足从事同一工作的雇员的月工资合计大于¥5000。输出结果按月工资的合计升序排列1.显示全部的非销售人员:job<>SALESMANselect * from emp where job<>'salesman'2.按工作分组同时求出工资的总和Select job,SUM(sal) from emp WHERE job<>SALESMAN GROUP BY job; 3.对分组条件进行限制

7、Select job,SUM(sal) from emp WHERE job<>SALESMAN GROUP BY job HAVING SUM(sal)>5000; 4.使用排序,按升序排列Select job,SUM(sal) su from emp WHERE job<>SALESMAN GROUP BY job HAVING SUM(sal)>5000 order by su; 分组的简单原则:只要一列上存在重复的内容才考虑用分组注意:分组函数可以嵌套使用,但是在组函数嵌套的时候不能再出现分组条件的查询语句范例:求出平均工资最高的部门错误代码:Sel

8、ect deptno,MAX(AVG(sal) from emp GROUP BY deptno;Select MAX(AVG(sal) from emp GROUP BY deptno;(正确)子查询范例:要求查询出比7654工资高的全部雇员信息首先:要知道7654雇员的工资是多少然后:以此查询结果为查询依据,只要其他工资大于sal,则表示符合条件首先:查询出比7654工资高的全部雇员信息select * from emp where sal>(select sal from emp where empno=7654);其次:与7788工作一样Select job from emp w

9、here empno=7788所以:select * from emp where sal>(select sal from emp where empno=7654) and job= (Select job from emp where empno=7788); ;数据库更新操作数据库的主要操作分为两种:1.数据库的查询操作SELECT2.数据库的更新操作 uUPDATE, DELETE, INSERT 此时为了保存原始的emp表的信息,在进行更新 删除 插入表前先将表复制一份Create table myemp AS select * from emp;此时数据已经复制出来添加数据

10、Insert into emp(empno,ename,job,hiredate,sal ,deptno)Values (7899,张三,清洁工,20-2月-2000,9000, 40);使用简略写法(并不推荐),因为现在是要添加所有字段的内容,所以可以不写上任何字段名称,只要值的数量和顺序和数据库表中的顺序一致。Insert into myemp values(7899,张三,清洁工,9000, 40);之前插入数据的时候,日期的格式是使用了表中固定好的格式,如果现在有这样一个日期”2009-10-10”日期格式,那么现在如何把这种格式的日期插入进去呢?使用TO_DATE()函数,将一个字符

11、串类型的数据变为DATE类型的数据。Insert into myemp(empno,ename,job,hiredate,sal ,deptno)Values (7899,张三,清洁工,TO_DATE(2009-07-19,yyyy-mm-dd),9000, 40);修改数据UPDATE 表名称 set 要修改的字段=新值,要修改的字段=新值.;UPDATE 表名称 set 要修改的字段=新值,要修改的字段=新值WHERE 修改条件.;修改数据删除全部: DELETE FROM 表名称 局部删除: DELETE FROM 表名称 WHERE 删除条件;事物处理范例:创建一张只包含10部分雇员的

12、一张临时表CREATE TABLE EMP10 AS SELECT * FROM EMP WHERE DEPTNO=10;打开一个oracle终端,进行删除操作DELETE FROM EMP10 WHERE SAL=2450;显示已经删除然后再打开另外一个oracle终端,查询到sal=2450这条数据还在,证明这条数据并没有被删除,这就是oracle事务的概念。事务处理: 就是保证数据操作的完整性,所有的操作要么同时成功要么同时失败。在ORACLE中对每一个连接到数据库中的窗口,都会与数据库建立一个Session。一个Session对数据库所做得修改不会马上反应到数据库的真实数据之上。是允许

13、回滚的,当一个Session提交所有操作之后,数据库才真正做出修改。进行同样的删除操作DELETE FROM EMP10 WHERE SAL=2450;结果它停住了,等待第一个终端操作结束再动。-这就是ORACLE死锁提交事务:COMMIT 回滚:RoolbackORACLE常用命令查看所有表select  table_name  from user_tables;显示表结构describe nchar_tst(nchar_tst为表名)查询练习1.列出至少有一个员工的所有部门信息第一步: 列出所有部门的员工数量Select deptno ,count(empno) fro

14、m emp group by deptno;第二步:列出员工大于1的部门 Select deptno ,count(empno) from emp group by deptno HAVING COUNT(empno)>1;第三步:通过多表关联查,把子查询做为一个查询出来select d.*,ed.couFROM dept d,(SELECT deptno,COUNT(empno) cou FROM empGROUP BY deptno HAVING COUNT(empno)>1) ed WHERE d.depno=ed.deptno ;2.列出薪金比SMITH多的所有员工第一步:

15、求出SMITH的工资SELECT salFROM EMP WHERE ENAME=SMITH;第二步:select ename from emp where sal>( SELECT salFROM EMP WHERE ENAME=SMITH);3 列出所有员工姓名及其直接上级的姓名此程序属于自身关联查询SELECT e.ename, d.ename FROM emp e ,emp d where e.mgr=d.empno;4. 列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称自身关联,查找mgr=empno的同时还要比较Hiredate第一步:SELECT e.empno,

16、e.enameFROM emp e, emp m WHERE e.mgr=m.empno AND e.hiredate<m.hiredate;查找e表的直属领导编号等于m表的员工,也就是说m表是领导表,m表的雇佣日期晚于e表第二步:SELECT e1.empno,e1.ename,d.dname FROM (SELECT e.empno,e.enameFROM emp e, emp m WHERE e.mgr=m.empno AND e.hiredate<m.hiredate) e1,dept dWHERE e1.deptno=d.deptno;ORA-00904 invalid

17、identifier 这个错误是因为 字段名写错了 检查下字段名,发现e1表的查询结果没有deptno字段,所以报错了!SELECT e1.empno,e1.ename,d.dname FROM (SELECT e.empno,e.ename,e.deptnoFROM emp e, emp m WHERE e.mgr=m.empno AND e.hiredate<m.hiredate) e1,dept dWHERE e1.deptno=d.deptno;李兴华给出的标准答案是:SELECT e.empno,e.ename,d.dname FROM emp e, emp m, dept d

18、WHERE e.mgr=m.empno AND e.hiredate<m.hiredate AND e.deptno=d.deptno;5. 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门左右关联问题SELECT d.deptno,d.dname,e.ename,e.empno FROM dept d, emp eWHERE d.deptno=e.deptno(+);查询结构少了40部门的信息,用连接操作SELECT d.deptno,d.dname,e.ename,e.empno FROM dept d, emp eWHERE d.deptno=e.deptno(+);6

19、. 列出所有”CLERK”(办事员)的姓名及部门名称, 部门的人数2.入手第一步:在emp表中查询出职位job为CLERK所在的部门名称(dept表)、.SELECT e.ename ,d.dnameFROM dept d,emp e WHERE e.job=CLERK AND e.deptno=d.deptno ;3.部门人数肯定要用分组查询,如果是分组查询肯定要用GROUP BY,而上面的语句明显不能用GROUP BY了,因为查询字段太多。所以把分组做子查询SELECT e.ename,d.dname,ed.couFROM emp e,dept d, (SELECT deptno,COUN

20、T(empno) cou FROM emp GROUP BY deptno) edWHERE job=CLERK AND e.deptno=d.deptno AND ed.deptno=e.deptno;7. 列出最低薪金大于1500的各种工作及此从事此工作的全部雇员人数SELECT job,COUNT(empno) FROM emp WHERE sal>1500 GROUP BY job;结果出来,但是是错的。李兴华分析一:按工作分组,分组条件最低工资大于1500SELECT job, MIN(sal) FROM emp GROUP BY job HAVING MIN(sal) >

21、;1500;分析二:SELECT e.job,COUNT(e.empno) FROM emp e WHERE e.job IN( SELECT job FROM emp GROUP BY job HAVING MIN(sal)>1500 ) GROUP BY e.job;8 列出在部门”SALES”(销售部)工作的员工的姓名,假定不知道销售部的部门编号1.Select deptno from dept where dname= SALES; 将第一步骤作为条件写子查询2.select ename from emp where deptno=( Select deptno from dep

22、t where dname=SALES);9. 列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,公司的工资等级。1.算出平均工资: Select AVG(sal) from emp 2. select * from emp where sal>( Select AVG(sal) from emp);答案:第一步求出公司的平均工资-à1,第二步:列出薪金高于平均工资的所有雇员的信息-à2第三步:要求所在部门肯定要与部门表关联查所在部门的信息,3. SELECT e.*,d.dname,d.loc FROM emp e,dept d WHERE sal>(S

23、ELECT AVG(sal) FROM emp ) AND e.deptno=d.deptno;第四步要想查询上级领导肯定要与自身关联4.SELECT e.empno,e.ename,m.ename,d.dname,d.deptno,d.loc FROM emp e,dept d,emp m WHERE e.sal>(SELECT AVG(sal) FROM emp ) AND e.deptno=d.deptno AND e.mgr=m.empnoe.mgr=m.empnoe表的领导编号等于m表的员工编号,emp表自身关联m表的员工=e表的领导,所以m.ename就是:"领导”

24、。(+);第五步:求出雇员的工资等级SELECT e.empno,e.ename,s.grade,m.ename,d.dname,d.deptno,d.loc FROM emp e,dept d,emp m,salgrade s WHERE e.sal>(SELECT AVG(sal) FROM emp ) AND e.deptno=d.deptno AND e.mgr=m.empno(+) AND e.sal BETWEEN s.losal AND s.hisal工资属于这个区间内表示这个等级。;10 列出与”SCOTT” 从事相同工作的所有员工及部门的名称。(dims)第一步:SEL

25、ECT job FROM emp e where e.ename=SCOTT; 第二步:SELECT e.ename, d.dname FROM emp e ,dept dwhere e.job=( SELECT job FROM emp e where e.ename=SCOTT)AND e.ename<>SCOTT AND e.deptno=d.deptno;11 列出薪金等于部门30中员工的薪金的所有员工的姓名和薪金(dims)SELECT e.ename,e.sal FROM emp e where sal IN(SELECT sal FROM emp where dept

26、no=30) AND deptno<>30;合理的情况是没有deptno=30的12 列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金.,部门名称Select sal from emp where sal >(MAX(SELECT sal FROM emp where deptno=30);答案: 在之前的程序改,使用>ALL比最大的还要大SELECT e.ename,e.sal,d.dname,d.loc FROM emp e ,dept d where sal >ALL(SELECT sal FROM emp where deptno=30) AND

27、 e.deptno<>30 AND e.deptno=d.deptno;13 列出在每个部门工作的员工数量,平均工资和平均服务期限第一步查询出每个部门的员工数量:SELECT d.dname,COUNT(empno) FROM emp e ,dept d WHERE e.deptno=d.deptno GROUP BY d.dname;答案:在第一步的基础上,第二步要读出平均工资和服务期限:尝试:SELECT d.dname,COUNT(empno),AVG(e.sal), AVG(e.hiredate) FROM emp e ,dept d WHERE e.deptno=d.de

28、ptno GROUP BY d.dname;SELECT d.dname,COUNT(empno),AVG(e.sal), AVG(MONTHS_BETWEEN(sysdate,e.hiredate)/12) 年FROM emp e ,dept d WHERE e.deptno=d.deptno GROUP BY d.dname;oracle中的months_between(date1,date2)函数可以实现年龄的计算,此函数的返回值为date1与date2之间的月数, 比如months_between(2008-8-8,2005-4-8)执行的结果是40(执行“select months_

29、between('2008-8-8','2005-4-8') from dual;”不包括双引号)。date1和date2都是DATE类型的,用SYSDATE可以获得系统时间,用现在的时间减去变量中的时间再与年龄总月 数比较即可实现这一功能。14 列出所有员工的姓名,部门名称和工资(dims)Select e.ename,d.dname,e.sal from emp e,dept d where e.deptno=d.deptno; 15 列出所有部门的详细信息和部门人数第一步: 这种题型肯定是多表关联子查询,首先列出部门的人数SELECT deptno dno

30、, COUNT(empno) cou FROM emp GROUP BY deptno第二步:把以上的结果当成一张临时表出现;SELECT d.*,ed.cou FROM dept d,(SELECT deptno dno,COUNT(empno) cou FROM emp CROUP BY deptno ) ed WHERE d.deptno=ed.dno;16 列出各种工作的最低工资及从事此工作的雇员姓名1查找工资最低的工作:SELECT job,MIN(sal) FROM emp GROUP BY job;2SELECT e.ename,e.job,cou.minsal FROM (SE

31、LECT job,MIN(sal) minsal, empno FROM emp GROUP BY job) cou,emp e WHERE e.empno= cou.empno ;ORA-00979: 不是 GROUP BY 表达式.错误答案:SELECT *FROM empWHERE sal IN(SELECT MIN(sal) FROM emp GROUP BY job);17 列出各个部门的MANAGER(经理)的最低薪金(dims)Select d.dname,MIN(e.sal)From emp e ,dept dWhere e.deptno=d.deptno AND e.job=

32、MANAGER group by d.dname;18 列出所有员工的年工资,按年薪从低到高排序在处理年薪的时候,要处理奖金,奖金要使用NVL函数处理SELECT ename,(sal+NVL(comm,0)*12 income FROM empORDER BY income;19 查出某个员工的上级主管,并要求出这些主管中的薪水超过3000SELECT DISTINCT m.* FROM emp e,emp mWHERE e.mgr=m.empno AND m.sal>3000;20 求出部门名称中,带s字符的部门员工的工资合计,部门人数查询部门表的部门名称,使用模糊查询,以确定部门的

33、编号SELECT deptno FROM dept WHERE dname LIKE %S%;以上面的结果作为查询的条件SELECT deptno,SUM(sal),COUNT(empno) FROM emp WHERE deptno IN (SELECT deptno FROM dept WHERE dname like %S%) GROUP BY deptno;21 给任职日期超过10年的人加薪10%UPDATE emp SET sal=sal+(sal*0.1)WHERE MONTHS_BETWEEN(sysdate,hiredate)/12 >10;创建表和管理表(重点)ORAC

34、LE 复制表的语法:CREATE TABLE 表名称 AS(子查询)如果现在子查询写的是:SELECT *FROM emp 表示将表结构和内容一起复制如果现在子查询写的是:SELECT * FROM emp WHERE 1=2; 加入一个永远不可能成立的条件,表示只是复制表结构不复制表内容。CREATE TABLE person_f(Pid VARCHAR(18),Name VARCHAR(200),Age NUMBER(3),Birthday DATE,SEX VARCHAR(2) DEFAULT 男);表的删除DELETE TABLE 表名称范例:删除person表 : DELETE TA

35、BLE person;表的修改范例:为person表增加address列ALTER TABLE person ADD( address VARCHAR(200) DEFAULT 暂无地址);为表重命名在Oracle中提供了RENAME命名,可以为表重新命名,但是此语法只能在Oracle中使用语法格式: RENAME 旧的表名称 TO 新的表名称范例:将person 重新命名为了 tpersonRENAME person TO miaofang;思考题分析:这是一道面试题,只能用笛卡尔乘机:Select e.country,d.country from country d ,country e

36、where e.country<>d.country;约束约束的分类:主键约束(PRIMARY KEY)主键约束一般都在id上使用,而且本身已经默认了内容不能为空,主键约束可以在建表的时候指定:范例:建立person表,在pid上增加主键约束CREATE TABLE person(Pid VARCHAR(18) PRIMARY KEY,Name VARCHAR(200),Age NUMBER(3),Birthday DATE,SEX VARCHAR(2) DEFAULT 男);insert into person values(null,'柯为权',123,TO_D

37、ATE(2009-07-19,yyyy-mm-dd),男');主键为空或者重复都会报错范例:将person中的pid指定名称CREATE TABLE person_a(Pid VARCHAR(18) ,Name VARCHAR(200),Age NUMBER(3),Birthday DATE,SEX VARCHAR(2) DEFAULT 男,CONSTRAINT person_pid_pk PRIMARY KEY(pid);Constraint kn'strent:约束;限制person_pid_pk:表示约束的名称非空约束(NOT NULL)CREATE TABLE pers

38、on_a(Pid VARCHAR(18) NOT NULL ,Name VARCHAR(200) NOT NULL,Age NUMBER(3),Birthday DATE,SEX VARCHAR(2) DEFAULT 男,CONSTRAINT person_pid_pk PRIMARY KEY(pid);表示插入了两个非空约束的声明,证明此时PID跟name是不允许为空的。唯一约束(UNIQUE)表示一个字段中的内容是唯一的,其他列不允许重复CREATE TABLE person_a(Pid VARCHAR(18) NOT NULL ,Name VARCHAR(200) UNIQUE NOT

39、NULL,Age NUMBER(3),Birthday DATE,SEX VARCHAR(2) DEFAULT 男,CONSTRAINT person_pid_pk PRIMARY KEY(pid);表示姓名唯一。检查约束 (CHECK)使用检查约束来判断一个列中插入的内容是否合法,例如:年龄,性别的取值范围。CREATE TABLE person_a(Pid VARCHAR(18) NOT NULL ,Name VARCHAR(200) NOT NULL,Age NUMBER(3) CHECK( age BETWEEN 0 AND 150),Birthday DATE,SEX VARCHAR

40、(2) DEFAULT 男 CHECK( sex I N (男,女,中性),CONSTRAINT person_pid_pk PRIMARY KEY(pid);修改约束(了解)一张表建立完成之后,则可以为其添加约束DROP TABLE person CASCADE CONSTRAINT;CREATE TABLE person(Pid VARCHAR(18) PRIMARY KEY,Name VARCHAR(200),Age NUMBER(3),Birthday DATE,SEX VARCHAR(2) DEFAULT 男);此时,需要为表中添加若干个约束,添加约束的语法如下:ALTER TABL

41、E 表名称 ADD CONSTRAINT 约束名称 约束类型(约束字段);关于约束类型的命名一定要统一:1) PRIMARY KEY:主键字段_PK2) UNIQUE:字段_UK3) CHECK:字段_CK4) FOREIGN KEY:父字段_子字段_FKALTER TABLE person ADD CONSTRAINT person_pid_PK PRIMARY KEY(pid);ALTER TABLE person ADD CONSTRAINT person_name_UK UNIQUE(pid);ALTER TABLE person ADD CONSTRAINT person_age_C

42、K CHECK(age BETWEEN 0 AND 150);ALTER TABLE person ADD CONSTRAINT person_sex_CK CHECK(sex IN (男,女,中);ROWNUM(重点)ROWNUM:表示行号,实际上此是一个列,但是这个列是一个伪列,此列可以在每张表中出现。范例:在查询雇员表上,加入ROWNUMSELECT ROWNUM, empno,ename,job,sal,hiredate FROM emp;从运行上看,ROWNUM本身采用自动编号的形式出现,有什么用处呢?例如,现在假设只想显示前5条记录。条件中:ROWNUM=5SELECT ROWNU

43、M,empno,ename,job,sal,hiredate FROM emp WHERE ROWNUM<=5;能不能查中间5条呢?如果现在想进行中间的截取操作,则只能采取子查询,例如现在假设每页显示5条,第2页应该显示610,那么对于数据库操作来讲,它在查询的时候应该首先查询110条,之后在查询的结果中取出后5条。如果要取出最后5条数据视图1. 表的建立:CREATE TABLE 表名称在ORACLE中的主要数据类型|-VARCHAR2(长度):表示一个字符串,有长度限制|-NUMBER():表示数字,可以表示整数或小数|-DATE:表示日期格式,日期要按照指定的格式编写|-CLOB:

44、存储大文本对象,海量文字2. 复制表:CREATE TABLE 表名称 AS 子查询3. 一般表建立之后不要修改,如果非要修改使用ALTER TABLE指令ALTER TABLE 有两种功能 | - 增加列:ALTER TABLE 表名称 ADD(字段名称 字段类型 DEFAULT 默认值) |- 修改列:ALTER TABLE 表名称 MODIFY(字段名称 字段类型 DEFAULT 默认值) 4. 约束:使用约束可以保证数据库表中的数据完整性5. 在SQL中约束一共分为以下五种:a) 但表上的约束 :|- PRIMARY KEY :一个实体表一般都要去建立一个主键,表示唯一的编号|- NO

45、T NULL: 一个列的内容不予许插入空值|- UNIQUE:表示此列的内容不允许重复|- CHECK:表示此列的内容设置的时候要有限制b)关联表上的约束: | - FOREIGN KEY 表示子表的取值与父表的取值有所关联|- 删除的时候应该先删除子表再删除父表|- 如果现在要删除父表,可以采用ORACLE的强制手段|-DROP TABLE 表名称 CASCADE CONSTRINT | -级联删除:ON DELETE CASCADE,当父表中的内容被删除掉之后,子表的对应内容也被删除掉。6. ROWNUM: 伪列:所有的记录中都存在此列,用以表示行的编号,在实际中可以通过此列并结合子查询完

46、成表中的部分数据显示。7. 集合的操作:并,交,差视图部分的知识点1. 掌握视图的作用及定义(重)2. 掌握序列的使用: SEQUENCE3. 掌握PowerDesiger设计工作的使用4. 了解同义词,了解用户管理5. 理解数据库的设计范式 视图视图的功能: 一个视图实际上就是封装了一条复杂的查询语句创建视图的语法:CREATE VIEW 视图名称 AS 子查询实际上此时的子查询就表示一条非常复杂的语句,范例:建立一个视图,包含全部的20部门的雇员信息(雇员编号,姓名,工作,雇佣日期)CREATE VIEW empv20 AS SELECT empno,ename,job,hiredate

47、FROM emp WHERE deptno=20;视图创建完成之后,就可以就可以像查找表那样直接对视图进行查询的操作范例:查询视图SELECT * FROM empv20;此时,是通过视图找到的20部门的所有数据,也就是发现,可以使用视图包装需要的查询语句。此时,此视图只包含了四个字段的信息,如果现在希望多包含一个 “工资”sal ,CREATE VIEW empv20 AS SELECT empno,ename,job,sal,hiredate FROM emp WHERE deptno=20; 出错,说明视图不能重名但是,如果所有的代码都这样去写肯定很麻烦,因为如果要修

48、改视图,肯定要先删视图,所以在ORACLE中为了方便用户修改视图,提供一个替换的命令,此时完整的视图创建语法 :CREATE OR REPLACE 视图名称 AS 子查询CREATE OR REPLACE VIEW empv20 AS SELECT empno,ename,job,sal,hiredate FROM emp WHERE deptno=20;视图可以封转复杂查询,那么下面封装一个之前已经存在的复杂查询:SELECT ename,(sal+NVL(comm,0)*12 income FROM empORDER BY income;如果在开发中每次都写如此之长的sql代码肯

49、定不方便,所以就应该把它建立成视图以方便用户查询操作;CREATE OR REPLACE VIEW empv21 AS SELECT ename,(sal+NVL(comm,0)*12 income FROM emp ORDER BY income;创建完视图之后,以后想得到之前的查询结果.直接写:SELECT *FROM empv21; 即可查询出结果范例:创建一个只包含20部门的雇员的视图CREATE OR REPLACE VIEW empv20 ASSELECT * FROM emp WHERE deptno=20;更新视图:在视图中是不应该包含真实数据的,而且在此程序中,创建的视图实际

50、上是存在创建条件的,此条件是deptno=20,如果将视图中的7369的部门编号改为30;范例:修改视图中的7369的部门编号UPDATE empv20 SET deptno=30 WHERE empno=7369;SELECT * FROM empv20; 此时,已经提示视图正常的进行了更新,重新查询视图之后,会发现在视图中已经没有7369这个雇员了,那么emp表中呢? -发现在emp表中的7369雇员的部门编号已经修改为30了,这样做明显不合适,因为创建视图的时候是有条件的,你一旦修改之后,则此条件就被破坏了,所以在创建视图的过程的SQL中提供了两个重要的参数: -WITH CHECK O

51、PTION:不能更新视图的创建条件范例:在创建视图中使用此参数CREATE OR REPLACE VIEW empv20 ASSELECT * FROM emp WHERE deptno=20 WITH CHECK OPTION; 完整的创建视图语法这时候再执行更新条件语句: UPDATE empv20 SET deptno=30 WHERE empno=7369;创建条件不能更新,那么其他字段呢?例如:现在将7369的雇员姓名修改Wie“史密斯”范例:修改视图中7369的雇员编号;UPDATE empv20 SET ename= 史密斯 WHERE empno=7369;已更新一行;但是,视

52、图的本身作用还是用来查询的,所以不应该允许更改,所以此时可以使用第二个参数:WITH READ ONLY: 创建的视图只读范例:创建只能读的视图CREATE OR REPLACE VIEW empv20 ASSELECT * FROM emp WHERE deptno=20 WITH READ ONLY;此时提示视图无法更改,是只读的。序列(重点)李兴华:在oracle中序列是最重要的。在很多数据库中都存在一个自动增长的列,如果现在要想在oracle中完成自动增长的功能,则只能依靠序列完成,所有的自动增长操作,需要用户手工完成处理。创建序列需要CREATE SEQUENCE系统权限。序列的创建

53、语法如下: CREATE SEQUENCE 序列名 INCREMENT BY 每次增长幅度n START WITH从哪开始; n MAXVALUE/ MINVALUE n|NOMAXVALUE最大值,最小值,没有最大值 CYCLE|NOCYCLE循环 CACHE n|NOCACHE;范例:创建一个myseq的序列,验证自动增长的操作CREATE SEQUENCE myseq;序列创建完成之后,所有的自动增长应该由用户自己处理,所以在序列中提供了以下的两种操作:NextVal :取得序列的下一个内容CurrVal :取得序列的当前内容范例:建立一张表以验证序列的操作CREATE TABLE te

54、stseq(next表示下一个值 NUMBER, curr 表示当前值 NUMBER );向表中添加数据,添加数据的时候需要手工使用序列范例: 使用序列INSERT INTO testseq(next,curr) VALUES( myseq.nextval, myseq.currval);将以上的语句执行5次.范例 : 查询testseq表,观察序列的变化从结果中发现,nextval始终在进行自动增长的操作,而curr始终取出当前操作的序列的结果;也就是说,现在的这种序列,每次增长的幅度是1,那么也可以修改序列的增长幅度:可以使用以下的两个参数: 每次的增长幅度:INCREATE BY 从哪里开始:START WITH范例:重新创建序列删除序列:DROP SEQUENCE myseq;CREATE SEQUENCE myseq INCREMENT 注意拼写BY 2;重建testseq表重新建立:DROP TABLE test2seq;CREATE TABLE test2seq(next NUMBER, curr NUMBER );INSERT INTO test2seq(next,curr) VALUES( myseq.nextval, myseq.currval);ORA

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论