如何实现显示一个记录字段,这个字段以两列多行顺序显示?

Tadpole0510 2006-10-26 10:04:30


记录1 记录2
---------------------------
记录3 记录4
-------------------------
。 。
。 。
。 。
。 。
记录n-1 记录n
...全文
86 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunjay117 2006-10-27
  • 打赏
  • 举报
回复
DataList datacoloumn=2
ldw701 2006-10-27
  • 打赏
  • 举报
回复
DataList datacoloumn=2

tete 2006-10-26
  • 打赏
  • 举报
回复
学习,以后可能用的倒
DePaul 2006-10-26
  • 打赏
  • 举报
回复
datalist columns=2
一、填空 1.在多进程Oracle实例系统中,进程分为用户进程、后台进程和服务进程。 2.标准的SQL语言语句类型可以分为:数据定义语句(DDL)、数据操纵语句(DML)和数据控制语句(DCL)。 3.在需要滤除查询结果中重复的时,必须使用关键字Distinct; 在需要返回查询结果中的所有时,可以使用关键字ALL。 4.当进模糊查询时,应使用关键字like和通配符问号(?)或百分号"%"。 5.Where子句可以接收From子句输出的数据,而HAVING子句则可以接收来自WHERE、FROM或GROUP BY子句的输入。 6.在SQL语句中,用于向表中插入数据的语句是Insert。 7.如果需要向表中插入一批已经存在的数据,可以在INSERT语句中使用Select语句。 8.使用Describe命令可以显示表的结构信息。 9.使用SQL*Plus的Get命令可以将文件检索到缓冲区,并且不执。 10.使用Save命令可以将缓冲区中的SQL命令保存到一个文件中,并且可以使用Run命令运该文件。 11.一个模式只能够被一个数据库对象所拥有,其创建的所有模式对象都保存在自己的模式中。 12.根据约束的作用域,约束可以分为表级约束和级约束两种。级约束是字段定义的一部分,只能够应用在一个上;而表级约束的定义独立于的定义,它可以应用于一个表中的多个。 13.填写下面的语句,使其可以为Class表的ID添加一个名为PK_CLASS_ID的主键约束。 ALTER TABLE Class Add ____________ PK_LASS_ID (Constraint) PRIMARY KEY ________ (ID) 14. 每个Oracle 10g数据库在创建后都有4个默认的数据库用户:system、sys、sysman和DBcnmp 15. Oracle提供了两种类型的权限:系统权限和对象权限。系统权限提供了在Oracle数据库系统范围内执某种任务的操作能力,而对象权限则是一种赋予用户在指定的数据库对象(如表、视图、过程等) 16. Oralce数据库在进物理备份有联机备份和脱机备份两种方式可供选择。 . 17. 从存储结构的角度来说,Oracle数据库可分为物理结构和逻辑结构。 18. 表空间是Oracle数据库中数据的逻辑组织,每个数据库至少有一个SYSTEM系统表空间。 19.视图是一个表示表的数据的数据库对象,它允许用户从一个表或一组表中通过一定的查询语句建立一个“虚表”。 20.序是一种可被多个用户使用的用于产生一系唯一数字的数据库对象。尤其适合多用户环境中,可以生成唯一的序号而没有磁盘I/O或事务处理锁定开销。 21. 一个表空间具有离线(OFFLINE)、在线(ONLINE)、只读(READ ONLY)、读写(READ WRITE)状态。 二、选择 1.在全局存储区SGA中,哪部分内存区域是循环使用的?( B ) A.数据缓冲区 B.日志缓冲区 C. 共享池 D.大池 2.如果一个服务器进程非正常终止,Oracle系统将使用下哪一个进程来释放它所占用的资源?( D ) A.DBWR B.LGWR C. SMON D.PMON 3. 如果要查询数据库中所有表的信息,应当使用下哪种数据字典视图?( A ) A. DBA视图 B. ALL视图 C. USER视图 D. 动态性能视图 4. 下哪一项是Oracle数据库中最小的存储分配单元? ( C ) A. 表空间 B. 段 C. 盘区 D. 数据块 5. 下面的各选项中哪一个正确描述了Oracle数据库的逻辑存储结构? ( A ) A. 表空间由段组成,段由盘区组成,盘区由数据块组成 B. 段由表空间组成,表空间由盘区组成,盘区由数据块组成 C. 盘区由数据块组成,数据块由段组成,段由表空间组成 D. 数据块由段组成,段由盘区组成,盘区由表空间组成 6. 下的哪个子句在SELECT语句中用于排序结果集?( D ) A. Having子句 B. Where子句 C. From子句 D. Order by子句 7. Having子句的作用是( B )。 a. 查询结果的分组条件 B. 组的筛选条件 C. 限定返回的的判断条件 D. 对结果集进排序 8. 下哪个函数可以把一个中的所有值相加求和? ( B ) A MAX B. SUM C. COUNT D. AVG 9. 下哪个子句是SELECT语句中必选项?( A ) A. FROM B.WHERE C.HAVING D. ORDER BY 10. 下哪个子句实现对一个结果集进分组和汇总?( D ) A.HAVING B. ORDER BY C. WHERE D. GROUP BY 11. 查询一个表的总记录数,可以采用_________统计函数。( C ) A. AVG(*) B. SUM(*) C. COUNT(*) D.MAX(*) 12. 要建立一个语句向Types表中插入数据,这个表只有两,T_ID和T_Name。如果要插入一数据,这一的T_ID值是100,T_Name值是RFUIT。应该使用的SQL语句是_____。( A ) A. INSERT INTO Type Values(100, ‘FRUIT’) B. SELECT * FROM Type WHERE T_ID=100 AND T_NAME=’FRUIT’ C. UPDATE SET T_ID=100 FROM Types WHERE T_Name=’FRUIT’ D. DELET * FROM Types WHERE T_ID=100 AND T_Name=’FRUIT’ 13. 用_____语句修改表的一或多数据。( A ) A.Update B.set C.Select D.Where 14. 使用什么命令可以清除表中所有的内容? ( D ) A.INSERT B.UPDATE C. DELETE D.TRUNCATE 15.关于模式的描述下哪一项不正确?( C ) A.表或索引等模式对象一定属于某一个模式 B.在Oracle数据库中,模式与数据库用户是一一对应的 C.一个表可以属于多个模式 D.一个模式可以拥有多个表 16.唯一约束与主键约束的一个区别是?( D ) A.唯一约束的的值不可以有重复值 B.唯一约束的的值可以不是唯一的 C.唯一约束的不可以为空值 D.唯一约束的可以为空值 17. 只能存储一个值的变量是哪种变量?( B ) A. 游标 B. 标量变量 C. 游标变量 D. 记录变量 18. 声明%TPYE类型的变量时,服务器将会做什么操作?( A ) A. 为该变量检索数据库的数据类型 B.复制一个变量 C.检索数据库中的数据 D.为该变量检索的数据类型和值 19.下哪一项可以正确地引用该记录变量中的一个值?( B ) A.rec_abc(1) B. rec_abc(1).col C. rec_abc.col D.rec_abc.first() 20. 在定义游标时使用的FOR UPDATE子句的作用是______。( C ) A.执游标 B. 执SQL语句的UPDATE语句 C.对要更新表的加锁 D. 都不对 21. 如果允许用户对视图进更新和插入操作,但是又要防止用户将不符合视图约束条件的记录添加到视图,应当在定义视图时指定下哪一个子句?( C ) A.WITH GRANT OPTION B. WITH READ ONLY C. WITH CHECK OPTION D. WITH CHECK ONLY 22. 如果想查看视图中哪些字段是可以更新的,应当查询哪一个数据字典视图?( D ) A. DBA_VIEWS B. DBA_OBJECTS C. DBA_CLU_COLUMNS D. DBA_UPDATABLE_COLUMNS 23. 在下各选项中,关于序的描述哪一项是不正确的?( D ) A. 序是Oracle提供的用于产生一系唯一数字的数据库对象 B.序并不占用实际的存储空间 C.使用序时,需要用到序的两个伪NEXTVAL与CURRVAL。其中,NEXTVAL 将返回序生成的下一个值,而CURRVAL返回序的当前值 D.在任何时候都可以使用序的伪CURRVAL,以返回当前序值 24. 在下各选项中,关于同义词的描述哪一项是不正确的?( B ) A.同义词是数据库对象的一个替代名,在使用同义词时,Oracle会将其翻译为对应的对象名称 B.在创建同义词时,所替代的模式对象必须存在 C.Oracle中的同义词分为公有同义词和私有同义词 D.公有同义词在数据库中所有的用户都可以使用;私有同义词由创建它的用户所拥有 25. 下哪个锁模式不属于Oracle?( D ) A. 共享锁 B.排他锁 C. 级共享锁 D. 死锁 26. 想在另一个模式中创建表,用户最少应该具有什么系统权限?( B ) A.CREATE TABLE B. CREATE ANY TABLE C. RESOURCE D. DBA 27. 如果要启用所有角色,则应该使用哪一个命令?( B ) A.SET ROLE ALL B. SET ROLE ENABLE ALL C. ALTER SESSION ALL D.ALTER USER ROLE ALL 28. 下哪一个操作可以用来为一个备份操作手动分配通道?( A ) A.ALLOCATE CHANNEL B. CREATE CHANNEL C. CHANNEL ALLOCATE D. CREATE LINK 29. 下哪一个命令用来显示RMAN通道的配置信息?( C ) A. LIST B. DISPLAY C.SHOW D.都可以 30. 下哪一个命令可以用来执不完全恢复?( B ) A. RESTORE DATABASE UNTIL B. RECOVER DATABASE UNTIL C. RECOVER DATA UNTIL D. RESTORE DATA UNTIL 三、简答题 1. 说明数据库模式与用户之间的区别。 答案: 数据库模式与用户之间的区别在于:用户是数据库的使用者和管理者,用户具有帐户状态、访问权限和操作权限等属性。模式是一系逻辑数据结构或对象的集合,是数据库中对象的组织和管理单位。 2. 简要游标的作用和游标操作的基本步骤。 答案: 游标的作用是将数据库的中数据检索出来后缓存,可以被PL/SQL程序一的读取并处理。支持一条、多条、零条记录的处理。 游标的基本操作步骤为: (1)声明游标,使用查询来定义游标的 (2)打开游标,使用PL/SQL命令OPEN来打开一个声明的游标 (3)提取数据,从游标中重复提取每条记录到数据结构中,直到数据集合被提交 (4)关闭游标,使用完游标后将其关闭 3.Oracle数据库的工作模式有哪两种?它们之间有有何区别? 答案: 在Oracle数据库中,数据库的操作模式分为专用服务器(DELICATED SERVER)模式和多线程服务器(MULTITHREADED SERVER)模式两种。其中,在专用服务器模式中为每个用户进程创建一个服务器进程,用户进程与服务器进程之间是1:1的关系;在共享服务器模式中,一个服务器进程可以为多个用户进程服务器。 4.说明数据库内存结构中SGA和PGA的组成,以及这两个内存区存放信息的区别。 答案: SGA区由数据缓冲区、共享池、重做日志缓冲区、大型池、JAVA池构成;PGA区由排序区、私有SQL区以及堆栈构成。SGA区是由Oracle分配的共享内存结构,包含一个数据库实例共享的数据和控制信息。当多个用户同时连接同一个实例时,SGA区数据供多个用户共享,所以SGA区又称为共享全局区。用户对数据库的各种操作主要在SGA区中进。该内存区随数据库实例的创建而分配,随实例的终止而释放。PGA区是在用户进程连接数据库,创建一个会话时,由Oracle为用户分配的内存区域,保存当前用户私有的数据和控制信息,因此该区又称为私有全局区。每个服务器进程只能访问自己的PGA区,所有服务器进程PGA区总和即为实例的PGA区的大小。 5. 说明数据库表空间的种类,以及不同类型表空间的作用。 答案: 数据库表空间分为系统表空间和非系统表空间两类,其中非系统表空间包括撤销表空间、临时表空间和用户表空间等。 SYSTEM表空间主要用于存储数据库的数据字典、PL/SQL程序的源代码和解释代码、数据库对象的定义。撤销表空间专门进回退信息的自动管理。临时表空间是专门进临时段管理的表空间。用户表空间用于分离不同应用的数据,而且能够减少读取数据文件时产生的I/O冲突。 6. 说明Oracle 10g数据库文本初始化参数文件与服务器初始化参数文件的区别。 答案: 文本初始化参数文件是一个本地的初始化参数文件,而服务器初始化参数文件是一个放在数据库服务器端的共享的二进制初始化参数文件。文本参数文件的修改是通过直接对文本的修改实现的,通过命令是无法将修改后的参数值写入该文件中,而服务器初始化参数文件是不能直接修改的,必须通过ALTER SYSTEM语句来进参数修改的。 7. 简述PL/SQL程序结构及各个部分的作用。 答案: PL/SQL程序的基本单元是语句块,所有的PL/SQL程序都是由语句块构成的,语句块之间可以相互嵌套,每个语句块完成特定的功能。  声明部分:以关键字DECLARE开始,BEGIN结束。主要用于声明变量、常量、数据类型、游标、异常处理名称以及本地(局部)子程序定义等。  执部分:是PL/SQL块的功能实现部分,以关键字BEGIN开始,EXCEPTION或END结束(如果PL/SQL块中没有异常处理部分,则以END结束)。该部分通过变量赋值、流程控制、数据查询、数据操纵、数据定义、事务控制、游标处理等实现块的功能。 异常处理部分:以关键字EXCEPTION开始,END结束。该部分用于处理该块执过程中产生的异常。 8. 说明触发器的种类和对应的作用对象、触发事件。 答案: 触发器包括DML触发器、INSTEAD-OF触发器和系统触发器。其中,DML触发器主要作用于表,其事件有INSERT、UPDATE、DELETE;INSTEAD-OF触发器主要主用于视图,其事件有INSERT、UPDATE、DELETE;系统触发器主要是DML事件和系统事件发生时调用的触发器,其中DML事件包括CREATE、DROP、ALTER等,系统事件包括LOGON、LOGOFF、STARTUP、SHUTDOWN、SERVERERROR等。 9.简述Oracle数据库角色的种类、作用,以及如何利用角色为用户授权。 答案: Oracle数据库中角色分为系统预定义的角色和用户自定义的角色两类。角色是一系权限的集合,可以先将权限授予角色,然后将角色授予具有相同权限的用户。 四、求解题 现有关系数据库如下: S(SNO,SNAME,CITY) P(PNO,PNAME,COLOR,WEIGHT) J(JNO,JNAME,CITY) SPJ(SNO,PNO,JNO,QTY) 其中,S为供应商,包含属性的含义依次是供应商代码、供应商名字、供应商所在城市;P为零件,包含属性的含义依次是零件代码、零件名字、颜色、重量;J为工程项目,包含属性的含义依次是工程项目代码、工程项目名字、工程项目所在城市;SPJ为供货关系,包含属性的含义依次是供应商代码、零件代码、工程项目代码,某供应商向某个项目供应数量的零件数量。 请用SQL语言完成如下问题: (1)查询供应工程J1零件P1的供应商号码SNO (2)查询供应工程J1零件为红色的供应商号码SNO (3)查询没有使用北京供应商生产的红色零件的工程号JNO 五、设计题(E-图) 六、PL/SQL语言程序设计题。 设学校环境如下:一个系有若干个专业,每个专业一年只招一个班,每个班有若干个学生: 现要建立关于系、学生、班级的数据库,关系模式为: 班CLASS(班号classid,专业名subject,系名deptname,入学年份enrolltime,人数num) 学生STUDENT(学号studentid,姓名name,年龄age,班号classid) 系DEPARTMENT(系号deptid,系名deptname) 试用PL/SQL语言完成以下功能: 1. 建表,在定义中要求声明: (1) 每个表的主外键。 (2) 每个班级的人数不能超过30人。 (3) 学生的年龄介于15到40岁之间。 (4) 学生姓名不能为空。 2. 插入如下数据 CLASS表 classid subject deptname enrolltime num 101 软件 计算机 1995 20 102 微电子 计算机 1996 30 111 无机化学 化学 1995 29 112 高分子化学 化学 1996 25 121 统计数学 数学 1995 20 131 现代语言 中文 1996 20 141 国际贸易 经济 1997 30 142 国际金融 经济 1996 14 STUDENT表 studentid name age classid 8101 张三 18 101 8102 钱四 16 121 8103 王玲 17 131 8105 李飞 19 102 8109 赵四 18 141 8110 李可 20 142 8201 张飞 18 111 8302 周瑜 16 112 8203 王亮 17 111 8305 董庆 19 102 8409 赵龙 18 101 8510 李丽 20 142 DEPARTMENT表 deptid deptname 001 数学 002 计算机 003 化学 004 中文 005 经济 3. 学校又新增加了一个物理系,编号为006 4. 学生张三退学,请更新相关的表。 1、有一张表test,有3个字段id,name,parentid。parentid是指父亲的id,请写一个sql语句,找出当过爷爷的id和name。 2、有一张学生表student,字段有student_id,name,即学号,名字。 还有一张选课表,字段有student_id,lesson_id。 还有一张课程表,字段lesson_id,lesson_name。 学生和课程是多对多的关系。 写一个sql语句,找出所有选了全部课程的学生。 3、有一张表person表,字段有id,name,age。age是年龄。 写一个sql语句,找出年龄最接近的2个人。 如有下面4条记录: 1,a,18 2,b,20 3,c,25 4,d,26 则输出3,4 emp表和dept表完成下练习 Emp员工表 empno ename job Mgr Hiredate Sal Comm Deptno 员工号 员工姓名 工作 上级编号 受雇日期 薪金 佣金 部门编号 Dept表 Deptno Dname Loc 部门编号 部门名称 地点 1.出至少有一个员工的所有部门。 select dept_id from s_emp where userid is not null; 2.出薪金比“chad”多的所有员工。 select id,salary from s_emp where salary>(select salary from s_emp where first_name='Chad'); 3.出所有员工的姓名及其直接上级的姓名。 select l.first_name as yuangong,e.first_name as laoban from s_emp e,s_emp l where e.manager_id=l.id(+); 4.出受雇日期早于其直接上级的所有员工。 select l.first_name as yuangong,e.first_name as laoban from s_emp e,s_emp l where e.manager_id=l.id(+) and l.start_date>e.start_date; 5.出部门名称和这些部门的员工信息,同时出那些没有员工的部门。 6.出所有“CLERK”(办事员)的姓名及其部门名称。 7.出最低薪金大于1500的各种工作。 8.出在部门“SALES”(销售部)工作的员工的姓名,假定不知道销售部的部门编号。 9.出薪金高于公司平均薪金的所有员工。 10.出与“SCOTT”从事相同工作的所有员工。 11.出薪金等于部门30中员工的薪金的所有员工的姓名和薪金。 12.出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金。 13.出在每个部门工作的员工数量、平均工资和平均服务期限。 14.出所有员工的姓名、部门名称和工资。 15.出从事同一种工作但属于不同部门的员工的一种组合。 16.出所有部门的详细信息和部门人数。 17.出各种工作的最低工资。 18.出各个部门的MANAGER(经理)的最低薪金。 19.出所有员工的年工资,按年薪从低到高排序。 原文:http://www.2xyd.cn/showtopic-524.aspx Oracle习题二附答案 使用scott/tiger的emp表完成练习 更多编程相关:http://www.2xyd.cn/showforum-11.aspx 答案: 1. select distinct dname from dept where deptno in (select distinct deptno from emp); 要查部门编号如果存在于emp 表中,说明这个部门有员工。 2. select ename,job,mgr,hiredate,sal from emp where sal> (select sal from emp where ename='SMITH'); 3. select e.ename, e.mgr , w.ename from emp e, emp w where e.mgr=w.empno; 4. select e.ename, e.mgr , e.hiredate,w.ename,w.hiredate from emp e, emp w where e.mgr=w.empno and e.hiredate< w.hiredate; 5. select e.ename,e.hiredate, d.dname,d.deptno from emp e, dept d where e.deptno (+)=d.deptno; 本例子使用的是外连接, 也可以用右连接。 select e.ename,e.hiredate, d.dname,d.deptno from emp e right join dept d on e.deptno=d.deptno; 6. select e.ename,e.hiredate,e.job, d.dname,d.deptno from emp e, dept d where e.deptno =d.deptno and e.job=upper('clerk'); 7. select job, min(sal) from emp group by job having min(sal)>1500; 8. select e.ename,d.dname from emp e,dept d 2楼 where e.deptno=d.deptno and d.dname=upper('sales'); 或者: select ename from emp where deptno = (select deptno from dept where dname=upper('SALES')); 9. select ename, job, sal from emp where sal> (select avg(sal) from emp ); 10. select ename, job from emp where job = (select job from emp where ename=upper('scott')); 11. select ename, sal,job from emp where sal in (select sal from emp where deptno=30); 12. select ename, sal,job from emp where sal >all (select sal from emp where deptno=30); 或者 select ename ,sal from emp where sal> (select max(sal) from emp where deptno=30); 13. select d.deptno,d.dname, count(e.ename), avg(e.sal), avg(months_between(sysdate,e.hiredate)) from emp e, dept d where e.deptno(+)= d.deptno group by d.deptno,dname; 或者下面的方法,这种方法更好理解,把需要汇总的生成一个视图e。 select e.*,d.dname , from (select deptno, count(ename) ,avg(sal),avg(months_between(sysdate,hiredate)) from emp group by deptno) e, dept d where e.deptno =d.deptno; 14. select d.dname, e.ename, sal+nvl(comm,0) from emp e, dept d where d.deptno=e.deptno; 15. select e.ename,e.job, e.deptno ,d.job, d.deptno from emp e, emp d where e.job=d.job and e.deptno<>d.deptno; 16. select count(e.ename),d.dname from emp e, dept d where e.deptno(+)= d.deptno group by e.deptno,d.dname; 或者写成 select d.deptno,e.*,d.dname from (select deptno,count(ename) from emp group by deptno) e,dept d where e.deptno(+)= d.deptno; 17. select job,min(sal+nvl(comm,0))from emp group by job; 18. select deptno,min(sal) from emp where job=upper('manager') group by deptno ; 19. select ename , (sal+nvl(comm,0))*12 yearsal from emp order by yearsal ; --1、出至少有一个雇员的所有部门   select distinct dname from dept where deptno in (select distinct deptno from emp);   --2、出薪金比"SMITH"多的所有雇员   select ename,sal from emp where sal>(select sal from emp where ename=upper('smith'));   --3、出所有雇员的姓名及其直接上级的姓名   select e.ename,m.ename from emp e,emp m where e.mgr=m.empno(+);   --4、出入职日期早于其直接上级的所有雇员   select ename from emp e where hiredate<(select hiredate from emp where empno=e.mgr);   --5、出部门名称和这些部门的雇员,同时出那些没有雇员的部门   select dname,ename from dept d left join emp e on d.deptno=e.deptno;   --6、出所有“CLERK”(办事员)的姓名及其部门名称   select ename,dname from emp e left join dept d on e.deptno=d.deptno where job=upper('clerk');   --7、出各种工作类别的最低薪金,显示最低薪金大于1500的记录   select job,min(sal) from emp group by job having min(sal)>1500;   --8、出从事“SALES”(销售)工作的雇员的姓名,假定不知道销售部的部门编号   select ename from emp where deptno = (select deptno from dept where dname=uppder('SALES'))   --9、出薪金高于公司平均水平的所有雇员   select ename from emp where sal>(select avg(sal) from emp);   --10、出与“SCOTT”从事相同工作的所有雇员   select ename from emp where job=(select job from emp where ename=upper('scott'));   --11、出某些雇员的姓名和薪金,条件是他们的薪金等于部门30中任何一个雇员的薪金   select ename,sal from emp where sal in (select sal from emp where deptno=30);   --12、出某些雇员的姓名和薪金,条件是他们的薪金高于部门30中所有雇员的薪金   select ename ,sal from emp where sal>(select max(sal) from emp where deptno=30);   --13、出每个部门的信息以及该部门中雇员的数量   select d.deptno,dname,count(ename) from dept d left join emp e on (d.deptno=e.deptno)   group by d.deptno,dname   --14、出所有雇员的雇员名称、部门名称和薪金   Select e.ename,d.dname,e.sal from emp e left join dept d on (d.deptno=e.deptno)   --15、出从事同一种工作但属于不同部门的雇员的不同组合   Select tba.ename,tbb.ename,tba.job,tbb.job,tba.deptno,tba.deptno   From emp tba,emp tbb   Where tba.job=tbb.job and tba.deptno<>tbb.deptno   --16、出分配有雇员数量的所有部门的详细信息,即使是分配有0个雇员   Select dept.deptno,dname,loc,count(empno)   From dept,emp   Where dept.deptno=emp.deptno(+)   Group by dept.deptno,dname,loc   --17、出各种类别工作的最低工资   Select min(sal) from emp group by job   --18、出各个部门的MANAGER(经理)的最低薪金   Select deptno,min(sal) from emp where job=upper(‘manager’) group by deptno   --19、出按年薪排序的所有雇员的年薪   select (sal+nvl(comm,0))*12 as avn from emp order by avn   --20、出薪金水平处于第四位的雇员   Select * from (Select ename,sal, rank() over (order by sal desc) as grade from emp) where grade=4 --1、选择部门30中的雇员   select * from emp where deptno=30;   --2、出所有办事员的姓名、编号和部门   select ename,empno,dname from emp e inner join dept d on e.deptno = d.deptno where job=upper(‘clerk’);   --3、找出佣金高于薪金的雇员   select * from emp where comm>sal;   --4、找出佣金高于薪金60%的雇员   select * from emp where comm>sal*0.6   --5、找出部门10中所有经理和部门20中的所有办事员的详细资料   select * from emp where (deptno=10 and job=upper(‘manager‘)) or (deptno=20 and job=upper(‘clerk ‘));   --6、找出部门10中所有经理、部门20中所有办事员,既不是经理又不是办事员但其薪金>=2000的所有雇员的详细资料   select * from emp where (deptno=10 and job=upper(‘manager‘)) or (deptno=20 and job=upper(‘clerk ‘)) or (job<>upper(‘manager’) and job<>upper(‘clerk’) and sal>=2000)   --7、找出收取佣金的雇员的不同工作   select distinct job from emp where comm>0;   --8、找出不收取佣金或收取的佣金低于100的雇员   select * from emp where nvl(comm,0)<100;   --9、找出各月最后一天受雇的所有雇员   select * from emp where hiredate= last_day(hiredate);   --10、找出早于25年之前受雇的雇员   select * from emp where months_between(sysdate,hiredate)/12>25;   select * from emp where hiredate显示只有首字母大写的所有雇员的姓名   select ename from emp where ename=initcap(ename);   --12、显示正好为6个字符的雇员姓名   select ename from emp where length(ename)=6   --13、显示不带有‘R‘的雇员姓名   Select ename from emp where ename not like ‘%R%’;   Select ename from emp where instr(ename,’R’)=0;   --14、显示所有雇员的姓名的前三个字符   select substr(ename,1,3) from emp   --15、显示所有雇员的姓名,用a替换所有‘A‘   Select replace(ename,’A’,’a’) from emp   --16、显示所有雇员的姓名以及满10年服务年限的日期   Select ename,add_months(hiredate,12*10) ‘服务年限的日期’ from emp   --17、显示雇员的详细资料,按姓名排序   Select * from emp order by ename   --18、显示雇员姓名,根据其服务年限,将最老的雇员排在最前面   Select ename from emp order by hiredate   --19、显示所有雇员的姓名、工作和薪金,按工作的降序顺序排序,而工作相同时按薪金升序   Select ename,job,sal from emp order by job desc ,sal asc   --20、显示所有雇员的姓名和加入公司的年份和月份,按雇员受雇日所在月排序,将最早年份的项目排在最前面   select ename,to_char(hiredate,‘yyyy‘),to_char(hiredate,‘mm‘) from emp order by hiredate asc   --21、显示在一个月为30天的情况下所有雇员的日薪金   select ename,sal/30 from emp;   --22、找出在(任何年份的)2月受聘的所有雇员   select * from emp where to_char(hiredate,‘mm‘)=‘02‘;   --23、对于每个雇员,显示其加入公司的天数   select ename,sysdate-hiredate from emp   --24、显示姓名字段的任何位置,包含 "A" 的所有雇员的姓名   select ename from emp where ename like ‘%A%‘;   select ename from emp where instr(ename,’A’,1)>0;   --25、以年、月和日显示所有雇员的服务年限   Select months_between(sysdate,hiredate)/12 as “年”, months_between(sysdate,hiredate) as “月”, sysdate-hiredate as “日” from emp
Microsoft Office Excel 新增系工具 帮 助 文 件 一、必要条件: 请确认您安装了Microsoft Office Excel2003、2007或2010非简装版,系统平台是:Winxp/vista/win7/2000/2003/2008。 二、功能介绍: 本软件以插件形式安装到Microsoft Office Excel的COM组件中,在菜单栏(Excel2003)或加载项(Excel2007和Excel2010)中增加“新增工具”菜单,使得Excel增加了如下十四大功能。《群发邮件功能》已经被《电脑报》在2011年第6期、《创建目录与批量改名功能》在《电脑报》2010年第45期上向国内外推介。 (一)群发邮件功能 1、制作工资条(成绩条)和工资簿(成绩簿):一张员工工资表 (学生成绩表)是由同一工作表中的同一单或多的表头下共存的若干条记录组成,要把单人的工资 (成绩)发给本人,用本软件可轻松地将每条记录分离,并在每一条记录的上方添加一个表头,以明确各项目的意义,还要在下方增加一个空,以便打印后裁剪。本软件还可以将工资条(成绩条)保存一个独立的工作簿文件。 2、工资条(成绩条)群发到邮箱:软件将工资条直接群发到每个人的邮箱,方便快捷,真正实现了无纸化高效办公。 3、工资条(成绩条)群发到手机:从Excel工作表的工资表中分离个人工资免费群发到手机,实现了快捷、便利、安全的目的。 4、工资条(成绩条)群发到个人文件夹:现在许多单位的个人信息都存放在服务器中由职工通过FTP查看,本软件能将同一个工作表中的每记录(工资条)另存为同名的个人文件夹中,并统一改名。例如:存到[独立]文件夹中的名称为张三、李四的两个文件,可以对应的分别转存到张三、李四两个文件夹中,并将这两个文件改名为[9月份工资]。 5、把工作表内容分类群发到邮件与手机:软件首先将工作表记录分类另存为工作簿文件,然后将这些文件以附件形式群发到指定的类别负责人邮箱。例如,年级成绩表由各班学生成绩组成,软件首先把本表另存为各班工作簿,然后再把每一班的工作簿群发给对应的班主任。 6、群发同附件邮件:将同标题、同内容、同附件的共性邮件群发到多个邮箱与手机,与邮箱群发不同的是能“逐个群发”,不受群发数量限制,不会被对方看到多个地址,不会被过滤成垃圾邮件。 7、自动进入网易邮箱:凡是126、163、yeah邮箱,可以一键进入。 (二)学校数据处理 1、学生编班与调班:根据各学校、各年级给学生编班的标准不同提供了两种编班方法供选择: (1)按总分排名编班:可以按学生总分(或某一学科分数)参照成绩、性别、特殊生等因素进一条龙排名,将学生均衡编入若干个教学班。分出来的教学班能够达到如下几项指标:(a)各班学生人数基本相等;(b) 各班男、女生学生数基本相等;(c)各个名次段人数各班基本相等;(d)平均成绩各班基本相等;(d)为满足不同用户要求,本软件可以不考虑男女生比例,仅按照成绩编班,还可以不考虑前若干名学生性别,仅考虑若干名之后学生的性别编班,也可以不按成绩随机分班;(e) 软件对编班结果冠以“准”字,目的是与正式编序号区别;(f)本软件具有智能提醒、检查与修复功能。引导您输入各项合理数据;为您自动修正性别、特殊生在录入时文本前后误输入的空格现象。 (2) 按各学科考分编班:有“预先挑班”要求的首先满足。然后主要考虑各学科平均分的小差距,同时考虑性别搭配,在上述条件满足的情况下,考虑特殊生搭配(特殊生提供了两栏,可以填写优秀生、班干部、问题生、住校生等)。分出来的教学班所达到的几项指标同(1)。 两种分班方法的设计思路是:前者首先给学生分类排名,然后“一条龙”分配到各班,所以班数整数倍段的学生人数各班仅相差1-2人;后者根据学生各学科分数、性别等情况,一一判断这个学生分配到哪个班合适,所以最后的每班各学科平均分、总平均分相差仅在半分之内。 编者强烈建议您的特殊要求不要超过两个,不能考虑太多的编班因素,不然会以牺牲“均衡性”为代价。考虑因素越多,分班各档次学生数及平均分差距越大。 (3)调班:调班需要学生考分差异小、男女等条件要匹配,主调学生还不能被再度调出……所以,纯手工调班是相当劳神的事情,本软件设计了按考号大小、姓名音序自动查找、调班标记颜色与备注等功能,使调班轻松自如。调班后可以轻击按钮跟踪各班男女生数、特殊生数、前若干名学生平均分、校前若干名学生在各班的分布等。 2、学生排名/班成绩分析:(1)可以在年级各班同表的成绩单上给学生进年级大排名,也可以进学生所在班内的排名,即可以进单学科排名、也可以进多学科、总分一次性排名。(2)班成绩分析是指各各班成绩汇总成一张独立的表格,内容包括:应考试人数、实考试人数、平均分、班内前若干名平均分、年级前若干名在各班内的分布等。 3、快速写评语:本软件附赠学生评语库,用户可以在评语库中方便的选择评语填写在学生成绩单上(以第二为准,测学生数),配合个人信息群发功能,快速发送到学生(或家长)个人邮箱。评语库中评语丰富,还可以随便增加与修改。 注:利用群发工资条(成绩表)功能,可以将由学校统一登统的校、年级学生考试成绩表拆分到每个班的成绩表后(保存在[分类文件]文件夹下的独立工作簿),群发到各班主任邮箱,再由班主任给本班学生在成绩记录添加评语,最终群发到学生(家长)的电子邮箱。 4、筛选各班前N名:筛选同一表格每个单位(班级)前N名的优秀人员(得分)的数据,删除其余人员的数据。 5、英语单词与解释分类:可以将中小学英语单词按照有几个连续字母相同来分类,例如可以将单词中含4个连续相同字母的单词分为一类(标注相同序号);还可以将中小学英语单词的解释按照有1个或2个汉字相同来分类(标注相同序号)。对于识记英语单词有很大的帮助。 (三)财务常用数据处理 1、添加与删除本页小计、累计与合计:可以方便的在帐目的每一页添加“本页小计”、“本页累计”,在尾页添加“本页小计”、“本页累计”与“合计”,还适用于分类筛选后的页面。通过“删除”键,可以方便的去除这些附加项。 2、人民币大小写等常用数据转换:可将人民币小写转换成大写、能四舍五入四舍五入、甩去零头取整、提取甩去的零头、工资纳税计算、分数或名次转等次、汉字转拼音、英语单词首字母转大写等。由于采用在单元格输入公式的方法,方便了用户的区域填充与公式修改。 (四)足球彩票分析专家 1、500WAN彩票网足彩分析:将500WAN彩票网上欧洲赔率数据下载到本地Microsoft Office Excel工作簿中,并且定时刷新网上数据,跟踪即时赔率与赛事的变化。用极短时间,在《欧赔走势》与《欧赔比较》等工作表中对各参数进有机组合与比较分析,给玩家展示出各时段的赔率规律,是足彩必赢的可靠工具。 2、okooo彩票网北单胜平负分析:将okooo彩票网上的模拟庄家盈亏和即时SP值,定时下载到同一工作簿中,自动监测与记录实时变化情况,让玩家一目了然,准确做出各种判断。 (五)任意文件、文件夹处理 1、任意文件移动:将指定文件夹下的文件移动到新建同名文件夹内 2、创建当前工作簿中各工作表的目录:提供了包含链接和不含链接两种目录格式,点击目录可轻松打开相当的工作表。目录创建后,可以在目录修改上随意修改目录。 3、创建选定文件夹下的文件目录:创建选定文件夹下所有文件目录,还可以包含该文件夹下所有子文件夹内的所有文件目录,也可以选择性的创建只创建Word、Excel文件目录,点击目录可轻松打开相当的文件。目录创建后,可以在目录修改上随意修改目录。 4、创建与本工作簿并的文件夹目录:目录创建后,点击目录可轻松打开相当的文件夹,还可以在目录修改随意修改目录。 5、工作表排序:工作簿中的若干工作表顺序混乱查找不方便,软件的工作表排序功能可以帮您将工作表按间序做升序与降序排。 (六)Word文档中的表与Excel工作簿中的工作表之间的转化 1、Word转Excel:把若干个Word文档中的表合并到Excel工作簿中的一个工作表中,可用于对下属填写的报名表(登记表)的汇总统计。 2、Excel转Word:把Excel工作簿的某个工作表中记录逐一拆分到对应的若干个Word文档中(表)中,可用于向下属发通知、通告等。 (七)多工作簿与当前工作簿中的工作表之间的转换 如下是不改变各工作表的内容转换操作: 1、多个工作簿中的多表导入到一个工作簿中的多工作表:将同一文件夹下的各工作簿中所有的非空工作表合并到当前工作簿中,各新建工作表仍保持原工作簿中的原工作表内容不变。新建工作表的命名有两种方式:一种是以原先各工作簿各[工作表名称]命名,另一种是以[原工作簿名称&原工作表名称]命名(这样可以保证工作表名称不重名)。 称命名为本工作簿中各工作表的名称,转化后的工作表内容不变。 2、工作簿与工作表名称互换:用于日报表的月底汇总。例如,到月底把每天统计的项目日报表,转化为各项目的每天情况。日报表形式:每天制作一个工作簿,每个工作簿中有N个工作表(统计N个项目), 一个月共有30个工作簿;要转化成的月底汇总表形式:共导出N个工作簿,每个工作簿的名称为项目名称,其中有30个工作表,工作表名称以1-30命名(本月日期)。转换过程中工作表内容和总数(30*N)不会改变。 3、抽取多工作簿中的同名工作表到同一新建簿中:从指定文件夹的所有工作簿中抽取与当前工作簿名称相同的工作表到同一个工作簿,这个工作簿的各工作表的名称为所抽取工作簿的名称,抽取后的工作表内容不变。 4、一个工作簿中的各工作表分解为独立的工作簿:将当前工作簿中若干个指定工作表拆分为独立的工作簿,独立的工作簿名称为当前工作簿中工作表的名称。 如下是增加或减少工作表的内容的合并或拆分操作: 5、多个工作簿中各个表头相同的工作表合并到同一个工作表中:合并后的表格的表头相同,为了明确每一条记录的来源,在表中增加一标注记录来看何簿何表。 6、多个工作簿中各个名称相同的工作表合并到同一个工作表中:合并后的表格的表头相同,为了明确每一条记录的来源,在表中增加一标注记录来看何簿何表。 7、多个工作簿中的所有工作表或指定工作表相同位置(区域)求和:打开(复制)一个空白的汇总表,表格格式与要汇总的表相同,凡鼠标选定单元格连续或不连续区域将对所有表格做累加计算。 8、当前工作表中每记录都独立拆分到独立工作簿:可用于制作每位职工的工资条。 9、当前工作表中记录按某一指定的类别拆分成组工作簿:类似Excel自带的高级筛选功能,可以把一个年级各班都在同一个工作表上的学生名单(成绩单)拆分成每个班的名单(成绩单),发给班主任。 (八)同一工作簿中各工作表的转换 1、多个工作表中各个表头相同的工作表合并到同一个工作表中:合并后的表格的表头相同,为了明确每一条记录的来源,在表中增加一标注记录来看何簿何表。 2、多个工作表中各个名称相同的工作表合并到同一个工作表中:合并后的表格的表头相同,为了明确每一条记录的来源,在表中增加一标注记录来看何簿何表。 3、多个工作表中相同位置的()集中到同一表:本工作簿中有若干格式相同的表,为了便于观察各表相同位置数据的变化,可以首先用鼠标选定要观察的区域,然后执本命令,则各工作表的同位置区域数据集中排到同一个表中,并自动标注该数据来自何表。 4、表头同数异字段名表合到新表:表头数相同,但各字段名不完全相同的工作表合并。合并结果为:总表记录数为各工作表的记录数之和,表头数为各工作表数之和,并在A多出一个标志,标记本条记录来源于哪个工作表。 5、多表(单表)同类数据合并与求和:其效果是:(a)标识重名的合成一条记录;(b)需要合并到一个单元格的数据为文本时用“/”号隔开,数据为数值通过求和合并到一个单元格中。例如,当前工作表或当前工作簿中的若干工作表中A有张三、李四、王五、李四,有相同字段“送货”,则本命令把A中的两个李四合并成一,同时将每个人在所有表中字段为“送货”的数量相加。 6、比较两表人员差异追加记录:其效果是向已有表中增加新表中的人员(数据)和表中所有人员的新增信息(数据),它适合于档案的逐步完善与保存。本命令可用于档案补充。例如:第一个表中有A、B、C三人,第二个表中有A、C、D、E四人,可以抽取两表中都有的A、C二人,还可以合并成A、B、C、D、E五人,并且可以追加一个表中的新的字段到另一个表。 7、按类别拆分一个工作表中的记录(组)到新表:是指将一个工作表中的多条记录按按照某一或某两的类别关键(第一关键字和第二关键字)字拆分成若干个结构相同的工作表,它适合于档案数据记录的分类。 8、按预设记录条数拆分记录到新表:可以将当前工作表的记录按指定的条数,拆分到若干个工作表中。 9、删除删除某为空或和为0的工作表:本操作将删除指定从第n起单元格中数字为空或为0的工作表,给合并有效的工作表扫清障碍。 10、检查两两单元格是否相同:由ID号意义相同的从表向主表合并记录时,往往先将从表记录粘贴到主表中,然后删除从表中的ID等与主表重复的记录,本命令用来比较两单元格(ID号)是否相同。 (九)工作表中的特殊处理 删除与标注重复、特殊数据操作代码用字典法编写,比Excel公式与高级筛选提速几十倍。 1、重名查找与姓名美化:本软件不仅能查找同字重名,还能查找同音重名。执此命令能够为某一的重复数据(包含汉字同音)染色,并且不同的重复数据染不同颜色,还可以把这些重复数据导出到一个新的工作表中。例如:可以将重名学生染同色,并可以导出到新的工作表中保存。 2、某重复数据标注与整删除:在每指定的各单元格中查找重复数据(同相的文本或数字),对重复的单元格染色、并在尾标注文字(例如“此重复”),还可以直接删除含重复数据的整(把所有重复删除仅保留一)。 3、某重复数据的重复次数计数,提取、删除各种形式的重复数据; 4、某带颜色单元格所在所的提取与删除; 5、取删除工作表中整为空值的,即删除整中各单元格无数据的; 6、删除某区域中含空单元格的; 7、删除整与另一完全重复的(把所有重复删除仅保留一)。 8、删除区域中某单元格包含相同内容的。 (十)单元格输入及区域操作 1、合并(还原)某区域内连续相同单元格:(1)在表格中某些的连续单元格中存在相同的数据,本命令可以把这些连续的单元格合并,在合并后的单元格中只保留一个数据。(2)许多表格中的某些连续存在爷父子孙的从属关系,本命令可以把每一级别的上一级单元格合并,在合并后的单元格中只保留一个数据。(3)合并后的单元格还可以用本命令来取消合并。 2、N中从有数据单元格向下填充:在N区域每一中从第一个有数据单元格向下面的空单元格填充,直到第二个有数据单元格,如果下面单元格没有数据,则填充到指定为止。 3、含有合并单元格的排序(整体排序):按照含有合并单元格中的数据进排序,用Excel的已有功能是办不到的,会出现“此操作要求合并单元格都具有相同大小”的提示,但用本插件中的命令易如反掌。 4、删除整表错误输入的空格:在数据输入过程中,各字符的前后难免会错误输入空格,给人工校对工作带来很大的麻烦。特别是对于数据的后面含有空格的情况,通过人工校对很难发现。本软件根据实际需要,提供了三种删除空格的命令:(1)将整个工作表中的所有空格全部删除;(2)保留数据内部字符间的空格,仅删除数据前后的空格;(3)删除数据前后的所有空格,并删除数据内部字符间一个以上的空格(仅保留一个)。 5、增加与标注空格操作:姓名美化,主要是将两字姓名的中间加一个空格,并将本居中对齐,加强美感。 6、更改已经输入数据后单元格格式(数据类型):本命令解决在单元格输入数据后利用[格式]-[单元格]-[数字],无法再重新定义单元格数据类型问题。可将数据类型在文本型、数值型、日期型之间随意互化。 7、词组逐字或字头逐个联想(词组逐字联想或声母逐个联想与指定快速选定):两个作用:1、快速查找指定的单元格所在的(快速定位);2、结合已有的词组等数据源,快捷输入数据。四个功能:1、逐个打入汉字联想;2、逐个打入拼音的声母联想;3、对于数据源中没有的数据可以直接在文本框中输入;4、存贮新建词组等数据,以备后期输入。 8、同文件夹下各工作簿各工作表中查找:可查找等于、包含、左包含、右包含某一内容的单元格。首先在打开的工作簿中查找,然后在本文件夹中的各工作簿中查找,查找结果以查找日志形式保存到桌面的文本文件中。 (十一)批注与图片导入导出 批量插入图片(文字):本软件提供了向工作表中批量插入图片的功能,有批量向批注中插入图片、批量向单元格填充图片、批量向单元格插入图片等选项,默认小二寸插入方式,也可以以厘米为单位,选择任意尺寸,原始图片默认jpg图片格式,也可以是gif、bmp、png等任意格式。软件还提供了仅插入文字功能。 被插入到单元格中的图片和所有批注,可以通过本软件一次性删除。 批量导出图片(文字):可保持图片原尺寸无损导出,也可以以工作表中的图片显示尺寸导出。导出图片的文件名有三种形式:1、图片序号;2、Excel中标注的名称;3、图片固有文件名称。 (十二)安全相关 1、制作超过打开次数或超过指定时间打开后能自动删除(自杀)的工作簿:有时候我们发送给别人的工作簿文件不希望永久保留,怎么办?本软件可以生成一种特殊的工作簿,你可以指定允许打开N次,当超过N次再打开,该工作簿会自杀;你也可以指定一个时间,超过这个指定时间打开后也会自动删除(自杀)。 2、解除密码:可解除当前工作表保护密码,解决因忘记密码而带来的麻烦; 3、隐藏与取消隐藏:可一次性显示被隐藏的若干个工作表,弥补了Excel自身的不足;可同时显示工作表中被隐藏的多与多,并能够调整高与宽为最合适的尺寸,检测数据区域内是否包含空与空。 4、显示恶意屏蔽:可显示被恶意屏蔽的菜单栏、工具栏、格式栏、工作表窗口右键菜单和工作表标签右键菜单。 (十三)页面设置与打印 1、分栏与分页排版:一般地,在工作表中都是一独占一条记录,但有时其所占数仅有2-3,打印下来,即浪费纸张又不美观,本软件可以像Word一样将这种版面进分栏重新排成原来数的N倍。记录顺序既可以按第一排完再折排版,也可以按每页指定固定数分栏排。 2、当前页与双面打印:软件能够一次性完成Excel文档的双面打印、还可以任选起止页进隔页打印,以实现更灵活的双面打印;软件还可以仅打印当前页。填补了Excel没有当前页打印和双面打印功能的空白,比Word中的打印功能还要强悍。 3、添加和删除实线分页符。添加实线分页符,可以起到按一定标准将一个工作表拆分成若干个工作表的效果,但又。 (十四)软件卸载 本软件在菜单中有临时卸载和长期卸载功能,也可以通过开始菜单卸载,还可以在控制面板卸载,软件卸载后不留残余,因而您可以放心试用。
CruiseYoung提供的带有详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 该资料是《Oracle SQL高级编程》的源代码 对应的书籍资料见: Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐) 基本信息 原书名: Pro Oracle SQL 原出版社: Apress 作者: (美)Karen Morton    Kerry Osborne    Robyn Sands    Riyaj Shamsudeen    Jared Still    译者: 朱浩波 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787115266149 上架时间:2011-11-9 出版日期:2011 年11月 开本:16开 页码:502 版次:1-1 主编推荐     资深Oracle专家力作,OakTable团队推荐     全面、独到、翔实,题材丰富     Oracle开发人员和DBA必备 内容简介     Oracle 数据库中的SQL是当今市场上功能最强大的SQL实现之一,而本书全面展示了这一工具的威力。如何才能让更多人有效地学习和掌握SQL呢?Karen Morton及其团队在本书中提供了专业的方案:先掌握语言特性,再学习Oracle为提升语言效率而加入的支持特性,进而将两者综合考虑并在工作中加以应用。作者通过总结各自多年的软件开发和教学培训经验,与大家分享了掌握Oracle SQL所独有的丰富功能的技巧所在,内容涵盖SQL执、联结、集合、分析函数、子句、事务处理等多个方面。读者可以学习到以下几个方面的技巧:     掌握Oracle数据库中独有的SQL强大特征;     读取并理解SQL执计划;     快速分析并改进表现欠佳的SQL;     通过提示及配置文件等来控制执计划;     在程序中优化查询而无需改动代码。     作为Oracle SQL经典著作之一,本书为SQL开发人员指明了前的方向,赋予了他们不断开拓的动力。 作者简介     KAREN MORTON 研究人员、教育家及顾问,Fidelity信息服务公司的资深数据库管理员和性能调优专家。她从20世纪90年代初就开始使用Oracle,从事 Oracle的教学工作也已经超过10年的时间。她是Oracle ACE,也是OakTable(Oracle社区中著名的“Oracle科学家”的非正式组织)的成员,经常在技术会议上演讲。她的著作还包括 Expert Oracle Practices和Beginning Oracle SQL,博客主页是karenmorton.blogspot.com。     KERRY OSBORNE  专注于Oracle咨询的Enkitec公司的创始人之一。从1982年开始使用Oracle(第2版)。他当过开发人员,也做过DBA,目前是 Oracle ACE总监和OakTable成员。最近几年,他专注于研究Oracle内部原理以及解决性能问题。他的博客主页是 kerryosborne.oracle-guy.com。     ROBYN SANDS 思科公司的软件工程师,为思科的客户设计开发嵌入式Oracle数据库产品。从1996年开始使用Oracle,在应用开发、大型系统实现以及性能评估方面具有丰富的经验。她是OakTable的成员,同时是Expert Oracle Practices (2010年 Apress出版)一书的合著者。     RIYAJ SHAMSUDEEN 专注于性能/数据恢复/电子商务的咨询公司OraInternals的首席数据库管理员和董事长。有近20年使用Oracle技术产品以及Oracle数据库管理员/Oracle数据库应用管理员的经验,是真正应用集群、性能调优以及数据库内部属性方面的专家。同时是一位演讲家及Oracle ACE。     JARED STILL 从1994年就开始使用Oracle。他认为对于SQL的学习是永无止境的,相信每一个查询Oracle数据库的人都需要精通SQL语言,才能写出高效的查询。他参与本书的编写就是为了帮助别人实现这一目标。 目录 封面 -11 封底 -10 扉页 -9 版权 -8 版权声明 -7 致谢 -6 目录 -5 第1章 SQL核心 1 1.1 SQL语言 1 1.2 数据库的接口 2 1.3 SQL*Plus 回顾 3 1.3.1 连接到数据库 3 1.3.2 配置SQL*Plus环境 4 1.3.3 执命令 6 1.4 5 个核心的SQL语句 8 1.5 SELECT语句 8 1.5.1 FROM子句 9 1.5.2 WHERE子句 11 1.5.3 GROUP BY子句 11 1.5.4 HAVING子句 12 1.5.5 SELECT表 12 1.5.6 ORDERBY子句 13 1.6 INSERT语句 14 1.6.1 单表插入 14 1.6.2 多表插入 15 1.7 UPDATE语句 17 1.8 DELETE语句 20 1.9 MERGE语句 22 1.10 小结 24 第2章 SQL执 25 2.1 Oracle架构基础 25 2.2 SGA-共享池 27 2.3 库高速缓存 28 2.4 完全相同的语句 29 2.5 SGA-缓冲区缓存 32 2.6 查询转换 35 2.7 视图合并 36 2.8 子查询解嵌套 39 2.9 谓语前推 42 2.10 使用物化视图进查询重写 44 2.11 确定执计划 46 2.12 执计划并取得数据 50 2.13 SQL执——总览 52 2.14 小结 53 第3章 访问和联结方法 55 3.1 全扫描访问方法 55 3.1.1 如何选择全扫描操作 56 3.1.2 全扫描与舍弃 59 3.1.3 全扫描与多块读取 60 3.1.4 全扫描与高水位线 60 3.2 索引扫描访问方法 65 3.2.1 索引结构 66 3.2.2 索引扫描类型 68 3.2.3 索引唯一扫描 71 3.2.4 索引范围扫描 72 3.2.5 索引全扫描 74 3.2.6 索引跳跃扫描 77 3.2.7 索引快速全扫描 79 3.3 联结方法 80 3.3.1 嵌套循环联结 81 3.3.2 排序-合并联结 83 3.3.3 散联结 84 3.3.4 笛卡儿联结 87 3.3.5 外联结 88 3.4 小结 94 第4章 SQL是关于集合的 95 4.1 以面向集合的思维方式来思考 95 4.1.1 从面向过程转变为基于集合的思维方式 96 4.1.2 面向过程vs.基于集合的思维方式:一个例子 100 4.2 集合运算 102 4.2.1 UNION和UNION ALL 103 4.2.2 MINUS 106 4.2.3 INTERSECT 107 4.3 集合与空值 108 4.3.1 空值与非直观结果 108 4.3.2 集合运算中的空值为 110 4.3.3 空值与GROUP BY和ORDER BY 112 4.3.4 空值与聚合函数 114 4.4 小结 114 第5章 关于问题 116 5.1 问出好的问题 116 5.2 提问的目的 117 5.3 问题的种类 117 5.4 关于问题的问题 119 5.5 关于数据的问题 121 5.6 建立逻辑表达式 126 5.7 小结 136 第6章 SQL执计划 137 6.1 解释计划 137 6.1.1 使用解释计划 137 6.1.2 理解解释计划可能达不到目的的方式 143 6.1.3 阅读计划 146 6.2 执计划 148 6.2.1 查看最近生成的SQL语句 149 6.2.2 查看相关执计划 149 6.2.3 收集执计划统计信息 151 6.2.4 标识SQL语句以便以后取回计划 153 6.2.5 深入理解DBMS_XPLAN的细节 156 6.2.6 使用计划信息来解决问题 161 6.3 小结 169 第7章 高级分组 170 7.1 基本的GROUP BY用法 171 7.2 HAVING子句 174 7.3 GROUP BY的“新”功能 175 7.4 GROUP BY的CUBE扩展 175 7.5 CUBE的实际应用 179 7.6 通过GROUPING()函数排除空值 185 7.7 用GROUPING()来扩展报告 186 7.8 使用GROUPING_ID()来扩展报告 187 7.9 GROUPING SETS与ROLLUP() 191 7.10 GROUP BY局限性 193 7.11 小结 196 第8章 分析函数 197 8.1 示例数据 197 8.2 分析函数剖析 198 8.3 函数表 199 8.4 聚合函数 200 8.4.1 跨越整个分区的聚合函数 201 8.4.2 细粒度窗口声明 201 8.4.3 默认窗口声明 202 8.5 Lead和Lag 202 8.5.1 语法和排序 202 8.5.2 例1:从前一中返回一个值 203 8.5.3 理解数据的位移 204 8.5.4 例2:从下一中返回一个值 204 8.6 First_value和Last_value 205 8.6.1 例子:使用First_value来计算最大值 206 8.6.2 例子:使用Last_value来计算最小值 207 8.7 其他分析函数 207 8.7.1 Nth_value(11gR2) 207 8.7.2 Rank 209 8.7.3 Dense_rank 210 8.7.4 Row_number 211 8.7.5 Ratio_to_report 211 8.7.6 Percent_rank 212 8.7.7 Percentile_cont 213 8.7.8 Percentile_disc 215 8.7.9 NTILE 215 8.7.10 Stddev 216 8.7.11 Listagg 217 8.8 性能调优 218 8.8.1 执计划 218 8.8.2 谓语 219 8.8.3 索引 220 8.9 高级话题 221 8.9.1 动态SQL 221 8.9.2 嵌套分析函数 222 8.9.3 并 223 8.9.4 PGA大小 224 8.10 组织为 224 8.11 小结 224 第9章 Model子句 225 9.1 电子表格 225 9.2 通过Model子句进引用 226 9.2.1 示例数据 226 9.2.2 剖析Model子句 227 9.2.3 规则 228 9.3 位置和符号引用 229 9.3.1 位置标记 229 9.3.2 符号标记 230 9.3.3 FOR循环 231 9.4 返回更新后的 232 9.5 求解顺序 233 9.5.1 求解顺序 233 9.5.2 规则求解顺序 235 9.6 聚合 237 9.7 迭代 237 9.7.1 一个例子 238 9.7.2 PRESENTV与空值 239 9.8 查找表 240 9.9 空值 242 9.10 使用Model子句进性能调优 243 9.10.1 执计划 243 9.10.2 谓语前推 246 9.10.3 物化视图 247 9.10.4 并 249 9.10.5 Model子句执中的分区 250 9.10.6 索引 251 9.11 子查询因子化 252 9.12 小结 253 第10章 子查询因子化 254 10.1 标准用法 254 10.2 SQL优化 257 10.2.1 测试执计划 257 10.2.2 跨多个执的测试 260 10.2.3 测试查询改变的影响 263 10.2.4 寻找其他优化机会 266 10.2.5 将子查询因子化应用到PL/SQL中 270 10.3 递归子查询 273 10.3.1 一个CONNECT BY的例子 274 10.3.2 使用RSF的例子 275 10.3.3 RSF的限制条件 276 10.3.4 与CONNECT BY的不同点 276 10.4 复制CONNECT BY的功能 277 10.4.1 LEVEL伪 278 10.4.2 SYS_CONNECT_BY_PATH函数 279 10.4.3 CONNECT_BY_ROOT运算符 281 10.4.4 CONNECT_BY_ISCYCLE伪和NOCYCLE参数 284 10.4.5 CONNECT_BY_ISLEAF伪 287 10.5 小结 291 第11章 半联结和反联结 292 11.1 半联结 292 11.2 半联结执计划 300 11.3 控制半联结执计划 305 11.3.1 使用提示控制半联结执计划 305 11.3.2 在实例级控制半联结执计划 308 11.4 半联结限制条件 310 11.5 半联结必要条件 312 11.6 反联结 312 11.7 反联结执计划 317 11.8 控制反联结执计划 326 11.8.1 使用提示控制反联结执计划 326 11.8.2 在实例级控制反联结执计划 327 11.9 反联结限制条件 330 11.10 反联结必要条件 333 11.11 小结 333 第12章 索引 334 12.1 理解索引 335 12.1.1 什么时候使用索引 335 12.1.2 的选择 337 12.1.3 空值问题 338 12.2 索引结构类型 339 12.2.1 B-树索引 339 12.2.2 位图索引 340 12.2.3 索引组织表 341 12.3 分区索引 343 12.3.1 局部索引 343 12.3.2 全局索引 345 12.3.3 散分区与范围分区 346 12.4 与应用特点相匹配的解决方案 348 12.4.1 压缩索引 348 12.4.2 基于函数的索引 350 12.4.3 反转键索引 353 12.4.4 降序索引 354 12.5 管理问题的解决方案 355 12.5.1 不可见索引 355 12.5.2 虚拟索引 356 12.5.3 位图联结索引 357 12.6 小结 359 第13章 SELECT以外的内容 360 13.1 INSERT 360 13.1.1 直接路径插入 360 13.1.2 多表插入 363 13.1.3 条件插入 364 13.1.4 DML错误日志 364 13.2 UPDATE 371 13.3 DELETE 376 13.4 MERGE 380 13.4.1 语法和用法 380 13.4.2 性能比较 383 13.5 小结 385 第14章 事务处理 386 14.1 什么是事务 386 14.2 事务的ACID属性 387 14.3 事务隔离级别 388 14.4 多版本读一致性 390 14.5 事务控制语句 391 14.5.1 Commit(提交) 391 14.5.2 Savepoint(保存点) 391 14.5.3 Rollback(回滚) 391 14.5.4 Set Transaction(设置事务) 391 14.5.5 Set Constraints(设置约束) 392 14.6 将运算分组为事务 392 14.7 订单录入模式 393 14.8 活动事务 399 14.9 使用保存点 400 14.10 序化事务 403 14.11 隔离事务 406 14.12 自治事务 409 14.13 小结 413 第15章 测试与质量保证 415 15.1 测试用例 416 15.2 测试方法 417 15.3 单元测试 418 15.4 回归测试 422 15.5 模式修改 422 15.6 重复单元测试 425 15.7 执计划比较 426 15.8 性能测量 432 15.9 在代码中加入性能测量 432 15.10 性能测试 436 15.11 破坏性测试 437 15.12 通过性能测量进系统检修 439 15.13 小结 442 第16章 计划稳定性与控制 443 16.1 计划不稳定性:理解这个问题 443 16.1.1 统计信息的变化 444 16.1.2 运环境的改变 446 16.1.3 SQL语句的改变 447 16.1.4 绑定变量窥视 448 16.2 识别执计划的不稳定性 450 16.2.1 抓取当前所运查询的数据 451 16.2.2 查看一条语句的性能历史 452 16.2.3 按照执计划聚合统计信息 454 16.2.4 寻找执计划的统计方差 454 16.2.5 在一个时间点附近检查偏差 456 16.3 执计划控制:解决问题 458 16.3.1 调整查询结构 459 16.3.2 适当使用常量 459 16.3.3 给优化器一些提示 459 16.4 执计划控制:不能直接访问代码 466 16.4.1 选项1:改变统计信息 467 16.4.2 选项2:改变数据库参数 469 16.4.3 选项3:增加或移除访问路径 469 16.4.4 选项4:应用基于提示的执计划控制机制 470 16.4.5 大纲 470 16.4.6 SQL概要文件 481 16.4.7 SQL执计划基线 496 16.4.8 基于提示的执计划控制机制总结 502 16.5 结论 502 媒体评论     本书作者全部是OakTable的成员,且具有15~29年丰富的Oracle开发经验。在研究一些被其他专门讨论Oracle SQL语言的参考书直接忽略的问题时,这种对Oracle数据库的长期钻研无疑是一个巨大的优势。     ——亚马逊读者评论 精彩内容     SQL核心     凯伦?莫顿(Karen Morton)     不管你是刚开始写SQL语句还是已经写过很多年了,学会写出“好的”SQL这个过程都需要具有很扎实的SQL核心语法和概念基础知识。本章对SQL语言的核心概念及其性能做了回顾,同时还描述了一些你应该已经很熟悉的常用SQL命令。对于那些以前曾经使用过SQL并且基础知识相当牢靠的读者来说,本章就是一个简要的复习,让你为后面更详细的SQL论述做好准备。如果你是一位SQL新人,你可能想要先阅读Beginning Oracle SQL这本书以确保掌握SQL的基础。不管是哪种情况,第1章的目的就是通过对5个核心SQL语句的快速浏览来衡量一下你的SQL水平,同时还概述了我们用来执SQL语句的工具:SQL*Plus。     1.1  SQL语言     SQL语言最早是IBM公司于20世纪70年代开发出来的,称为结构化英文查询语言,简称为SEQUEL。该语言是基于E.F.Codd在1969年提出的关系型数据库管理系统(RDBMS)的。后来因为商标的纠纷,其简称又进一步缩写为SQL。1986年和1987年,ANSI(美国国家标准化组织)和ISO(国际标准化组织)先后将SQL语言采纳为标准语言。而人们并不熟悉的是,ANSI官方曾将SQL语言的读音确定为“S-Q-L”。绝大多数人,包括我本人,都还在使用“sequel”的读音,只是因为这样读起来更顺口一些。     SQL的目的就是简单地提供一个到数据库的接口,在本书指的是Oracle数据库。每一条SQL语句对于数据库来说就是一条命令或指令。SQL与其他编程语言(如C或Java)的区别就在于它是要处理数据集合而不是一的数据。语言本身也不需要你提供如何导航到数据的指令——这是在后台透明地进的。但你将在后面的章节中看到,如果想在Oracle中写出高效的SQL语句,了解数据及其在数据库中的存储方式与存储位置是很重要的。     由于不同的供应商(例如甲骨文、IBM和微软)实现SQL核心功能的机制相差无几,所以基于某一种数据库所学的技巧同样可以应用到其他类型的数据库上。你基本上可以利用同样的SQL语句来进数据的查询、插入、更新和删除,以及创建、修改和删除对象,而不必管数据库的供应商是哪家。     尽管SQL是各种关系型数据库管理系统的标准语言,但实际上它并不一定是关系型的。在本书后面我将就这一点稍作扩展。如果想要了解更多的细节,我推荐大家阅读C.J.Date的SQL and Relational Theory一书。需要铭记于心的一点是SQL语言并不总是严格遵守关系模型的——它根本就没有实现关系模型的某些要素,同时还不恰当地实现了一些要素。事实上,既然SQL是基于关系模型的,那么要想写出尽可能正确高效的SQL语句,你不仅必须要理解SQL语言,还要理解关系模型。     1.2  数据库的接口     多年以来人们开发出多种途径来传递SQL语句到数据库并获得结果。Oracle数据库的本地接口界面是Oracle调用界面(OCI)。OCI将由Oracle内核传送而来的查询语句发送到数据库。当使用某种Oracle工具如SQL*Plus或者SQL Developer时,你都在使用OCI。其他的Oracle工具如SQL*Loader、数据泵(Data Pump)以及Real Application Testing (RAT)既使用OCI,也可以使用语言特定的接口,如Oracle JDBC-OCI、ODP.Net、Oracle预编译器、Oracle ODBC以及Oracle C++调用接口(OCCI)驱动器。     当使用编程语言(如COBOL或C语言)时,你所写的语句被称为嵌入式的SQL语句并且在应用程序编译之前会由SQL预处理器进预处理。代码清单1-1是一段可以在C/C++程序块中使用的SQL语句的例子。     代码清单1-1  C/C++程序块中所嵌入的SQL语句     其他工具,例如SQL*Plus和SQL Developer,都是交互式的工具。你输入并执命令,然后获得相应的输出。交互式工具并不需要在运代码前先精确编译,你只需要输入想要执的命令即可。代码清单1-2是一段使用SQL*Plus执语句的例子。     代码清单1-2  使用SQL*Plus执SQL语句     在本书中,为了保持一致性我们所用的示例代码清单都使用SQL*Plus工具,但需要记住的是,不管你是用什么方法或工具来输入和执SQL语句,所有的事情最后都要通过OCI来传递到数据库。这里的主旨就是不管你所使用的是什么工具,其本地接口都是一样的。     1.3  SQL*Plus回顾     SQL*Plus是一个不管采用哪个安装平台(Windows或Unix)都会提供的命令工具。它是一个用来输入和执SQL语句并显示输出结果的纯文本环境。用该工具可以直接输入、编辑命令,可以一条条地保存和执命令或者通过脚本文件来进,然后将输出结果以很精美格式的报表输出。要启动SQL*Plus你只需要在主机的命令提示符后敲入sqlplus即可。     1.3.1  连接到数据库     有多种方法可以通过SQL*Plus连接数据库。然而在连接之前,你还需要在$ORACLE_HOME/ network/admin/tnsnames.ora这个文件中登记想要连接的数据库。有两种通常使用的方法,或者如代码清单1-3所示那样在启动SQL*Plus时提供连接信息,或者如代码清单1-4所示那样在启动SQL*Plus以后使用connect命令。     代码清单1-3  通过窗口命令提示符连接到SQL*Plus     如果想要启动SQL*Plus而又不显示登录到数据库后的提示,可以在启动SQL*Plus时使用/nolog选项。     代码清单1-4  通过SQL>提示符连接SQL*Plus并登录到数据库     1.3.2  配置SQL*Plus环境     SQL*Plus有很多的命令可以让你来定制工作环境和显示选项。代码清单1-5所示是在SQL>提示符下输入help index命令后显示出来的可用的命令。     代码清单1-5  SQL*Plus命令表     set命令是用来定制工作环境的最基本的命令。代码清单1-6为set命令的帮助文本。     代码清单1-6  SQL*Plus的SET命令     有了上面这些可用命令,你就能够很轻松地定制最适合你的运环境了。但有一点要铭记于心的就是当你退出或关闭SQL*Plus的时候,这些设置命令就不再被保留了。为了避免每次使用SQL*Plus时都重新敲入一遍这些设置命令,你可以创建一个login.sql文件。事实上每次启动SQL*Plus的时候它都会默认去读两个文件。第一个是$ORACLE_HOME/sqlplus/admin目录下的glogin.sql文件。如果找到了这个文件,它就会被读进来,文件中的命令语句也会被执。这样就可以把那些定制你的会话体验的SQL*Plus命令和SQL语句保存起来。     在读取glogin.sql文件以后,SQL*Plus会进一步寻找login.sql文件。这个文件必须在SQL*Plus的启动文件夹中或者包含在环境变量SQLPATH所指向的文件夹路径中。在login.sql文件中的所有命令优先级都比glogin.sql文件中的命令高。从10g开始,Oracle在每次你启动SQL*Plus或者从SQL*Plus里执connect命令的时候都会同时去读取glogin.sql和login.sql这两个文件。在Oracle 10g之前,login.sql脚本文件只有在SQL*Plus启动的时候才会被执。代码清单1-7是一个常见的login.sql文件内容。     代码清单1-7  一个常见的login.sql文件     注意这里在SET SQLPROMPT中使用的变量_user和_connect_identifier。它们是预定义变量的两个示例。你可以在login.sql文件中或者任何你创建的脚本文件中使用下面这些预定义变量:     ·_connect_identifier     ·_date     ·_editor(这个变量指定了当你使用edit命令的时候启动哪个编辑器)     ·_o_version     ·_o_release     ·_privilege     ·_sqlplus_release     ·_user     1.3.3  执命令     有两种命令可以在SQL*Plus中执:SQL语句和SQL*Plus命令。代码清单1-5和代码清单1-6中所出的SQL*Plus命令对于SQL*Plus来说是特有的命令,可以用来定制运环境并且可以运SQL*Plus特有的命令,例如DESCRIBE和CONNECT。要想执一个SQL*Plus命令,你只需在命令提示符后输入该命令然后敲回车,命令会自动被执。另一方面,如果要执SQL语句,就必须使用一个特定字符来表明你想要执输入的语句,分号(;)或者斜线(/)都可以。使用分号的话可以直接放在输入命令的后面或者放在接下来的空中,而斜线则必须放在接下来的空中才可以被识别。代码清单1-8展示了如何使用这两种符号。     代码清单1-8  执字符的用法     注意第5个在语句最后面加了一个斜线(/)的例子。光标移动到了下一而不是立即执语句命令。接下来,如果你再按一下回车键,语句就会被放入SQL*Plus的缓冲器中,但是也不执。如果想要查看SQL*Plus缓冲器中的内容,可以使用list命令(也可以简写为l)。接下来如果你想在缓冲器中通过使用斜线(/)来执语句[尽管斜线(/)命令本来就是这样来用的]在这里也将会返回一个错误。这是因为你最初在SQL语句的结尾敲入了一个斜线(/),而斜线(/)并不是一个有效的SQL命令,从而在语句想要执的时候报错。     另外一种执命令的方法是把命令放到一个文件中。你可以在SQL*Plus之外直接用文本编辑器生成这些文件,也可以在SQL*Plus中使用EDIT命令来直接调用编辑器。如果已经有了一个文件,EDIT命令可以打开这个文件,如果没有的话就会创建新的文件。文件必须放在默认文件夹中,否则你必须指定文件的全路径。想要设定所选择的编辑器,你只需要利用命令define_ editor='//myeditor.exe'来设置预定义变量_editor。具有.sql扩展名的文件在执的时候不必敲入扩展名,通过@或START命令都可以执。代码清单1-9中出了这两个命令的用法。     代码清单1-9  执.sql脚本文件     SQL*Plus具有很多特性和选项,以致于多得在这里不能一一举。就本书需要而言,这种概述就已经足够了。但是,Oracle文档对SQL*Plus的用法给出了指导,而且很多的书,比如Beginning Oracle SQL,都对SQL*Plus作了更为深入的阐述,如果感兴趣你可以参考。     1.4  5个核心的SQL语句     SQL语言有很多不同的语句,但在整个职业生涯中,你可能只会用到其中很少的一部分。不过你所使用的几乎其他任何产品不也是这样的吗?据说有一个统计结果是,绝大多数人都仅使用了他们常用的软件产品或编程语言所有功能的20%甚至更少。我不知道这个统计真实与否,但以我的经验来看,这似乎是很准确的。我发现同样的基本SQL语句格式在大多数应用中使用了将近20年了。极少数的人使用过SQL提供的所有功能——即使对于那些他们确实经常使用的功能也常常用得不是很恰当。显而易见,我们不可能覆盖SQL语言的所有语句以及它们的选项。本书的目的在于让你能够深入理解那些最常用的SQL语句并帮助你更高效地使用它们。     在本书中,我们将重点讨论5个最常用的SQL语句,它们分别为SELECT、INSERT、UPDATE、DELETE以及MERGE。尽管这些核心语句都将逐个讲解,但重中之重还是SELECT语句。将这5个语句用好了将会为你在日常工作中用好SQL语言打下坚实的基础。     1.5  SELECT语句     SELECT语句用来从一个或多个表中或者其他数据库对象中提取数据。你应该已经很熟悉SELECT语句的基础知识了,所以我将不再从一个初学者的角度来介绍SELECT语句,而是首先回顾一下SELECT语句的执逻辑。对于如何来写一个基本的SELECT语句你应该已经学习过了,但为了培养基本的思维模式,你要一直写出符合语法规则的高效SQL语句,你需要理解SQL语句是如何执的。     一个查询语句在逻辑上的处理方式可能会与实际物理处理过程大相径庭。Oracle基于查询成本的优化器(cost-based optimizer , CBO)用来产生实际的执计划。我们在后面的章节中将会讲解优化器是干什么的,如何来实现其功能的以及为什么要进优化。目前,我们需要关心的是优化器将会决定如何访问表、按照什么样的顺序来处理它们,以及如何将多个表联结起来及如何使用筛选器。查询的处理在逻辑上是按照特定的顺序的,但是,优化器所选择的物理执计划可能会按照完全不同的顺序来实际执这些步骤。代码清单1-10是一段包含SELECT语句的主要子句的查询片段,在其中标出了每一个子句的逻辑处理顺序。     代码清单1-10  查询语句的逻辑处理顺序     你应该立刻注意到SQL有别于其他编程语言的一点在于首先处理的并不是写在第一的语句(SELECT语句),而是FROM子句。注意在这个代码清单中我给出了两个不同的FROM子句。标记为1.1的那个FROM子句表示的是当使用ANSI语法时的不同。我们可以把处理过程中的每一个步骤想象为生成一个临时的数据集。随着每个处理步骤的进,这个数据集被不断地操作直到生成最终的处理结果。查询返回给调用者的就是这个最终结果数据集。     为了更详细地了解SELECT语句的每个部分,你可以参考代码清单1-11所示的查询语句,该语句返回的结果集为下订单超过4次的女顾客的表。     代码清单1-11  下订单超过4次的女顾客查询语句     1.5.1  FROM子句     FROM子句出了所查询数据的源对象。这个子句可以包含表、视图、物化视图、分区或子分区,或者你可以建立一个子查询来生成子对象。如果使用了多个源对象,其逻辑处理阶段也将会应用到每一个联结类型以及谓词ON(如步骤1.1所示)。在本书后面的章节中你将会进一步了解联结类型的更多细节,但注意在处理联结语句的时候是按照下面的顺序来进的:     (1) 交叉联结,也称为笛卡儿乘积;     (2) 内联结;     (3) 外联结。     在代码清单1-11所示的查询例子中,FROM子句出了两张表:customers和orders,通过customer_id来联结。因此,当处理这一信息时,FROM子句所生成的初始数据集将会包含这两张表中customer_id相匹配的。在本例中结果集将会包含105。为了验证这一点,只要执例子中的前4,如代码清单1-12所示。     代码清单1-12  仅通过FROM子句的部分查询语句的执     注意 为了使之很好地适应页面我手工调整了输出结果,实际输出结果在页面上超过105。     1.5.2  WHERE子句     WHERE子句提供了一种方法,可以按照条件来限制查询最终返回结果集的数。每个条件或者谓语都是以两个值或表达式相比较的形式出现的。比较的结果要么是匹配(值为TRUE)要么是不匹配(值为FALSE)。如果比较的结果是FALSE,那么相应的不会被包含在最终结果集中。     这里我需要稍微偏离一下主题,来谈一谈与这一步相关的SQL中的一个重要方面。事实上,SQL中逻辑比较的可能结果是TRUE、FALSE以及未知。当其中包含空值(null)的时候比较的结果就会是未知。空值与任何值比较或者用在表达式中都会得到空值,或者是未知。一个空值代表一个相应值的缺失,并且可能因为SQL语言中的不同部分对空值的处理不同而令人费解。关于空值是如何影响SQL语句执的话题将会贯穿本书,但在这里我不得不先提及一下这个话题。我之前所说的还是基本正确的,一个比较的返回值将会是TRUE或者FALSE。你会发现当进筛选的比较条件中包含空值的时候,将作为FALSE来对待。     在我们的例子中,只有一个将结果限定为下了订单的女性消费者的谓语。如果你查看FROM子句执之后的中间结果(见代码清单1-12),你会发现105中仅有31是由女性消费者所下的订单(gender = 'F')。因此,在应用了WHERE子句以后,中间结果集将从105减少到31。     应用WHERE子句以后得到了更精确的结果集。注意,在这里使用的是“精确的结果集”。我的意思是说现在已经得到了能够满足你查询需求的数据。其他子句(GROUP BY, HAVING)也许可以用来聚合并且进一步限制调用程序会接收到的最终的结果集,但需要注意的很重要的一点是,目前已经得到了查询计算最终结果所需的所有数据。     WHERE子句的目的是限制或者减小结果集。你所使用的限制条件越少,最终返回的结果集中包含的数据就会越多。你需要返回的数据越多,执查询的时间也就越长。     1.5.3  GROUP BY子句     GROUP BY子句将执FROM和WHERE子句后得到的经过筛选后的结果集进聚合。查询出来的结果按照GROUP BY子句中出的表达式进分组,来为每一个分组得出一汇总结果。你可以按照FROM子句中所出对象的任意字段分组,即使你并不想在输出结果表中显示。相反,Select表中的任何非聚合字段都必须包括在GROUP BY表达式中。     GROUP BY子句中还可以包含两个附加的运算:ROLLUP 和CUBE。ROLLUP运算用来产生部分求和值,CUBE运算用来求得交互分类值。当你使用这两种运算中任意一个的时候,你将会得到不止一的汇总信息。在第7章中将会对这两个运算进更详细的讨论。     在示例查询中,需要按照customer_id来进分组。这就意味着对于每一个唯一的customer_id只会返回一值。在WHERE子句执后所得到的代表下订单的女性消费者的31订单中,有11个独特的customer_id值,如代码清单1-13所示。     代码清单1-13  截至GROUP BY子句的部分查询执     你会发现查询的结果是经过分组的,但并没有排序。表面上看结果好像是按照order_ct字段排序的,但这仅仅是个巧合而不是确定的为。需要记住的很重要的一点是:GROUP BY子句并不确定结果数据的排序。如果你需要结果按照特定的顺序,则必须指定一个order by子句。     1.5.4  HAVING子句     HAVING子句将分组汇总后的查询结果限定为只有该子句中的条件为真的数据。除非你使用HAVING子句,否则将返回所有的汇总。事实上,GROUP BY子句和HAVING子句的位置是可以互换的,谁先谁后都无关紧要。但是,似乎在编码中将GROUP BY子句放在前面更有意义一些,因为GROUP BY子句在逻辑上是先执的。从本质上来说,HAVING子句是在GROUP BY子句执后用来筛选汇总值的第二个WHERE子句。     在我们的查询例子中,HAVING子句HAVING COUNT(o.order_id) > 4,将分组数据从11减少到2。这一点你可以通过查看GROUP BY子句应用后返回的结果来确认,如代码清单1-13所示。注意仅有146和147号消费者所下的订单数超过4次。这样就产生了组成最终结果集的两数据。     1.5.5  SELECT表     SELECT出查询的返回最终结果集中需要显示哪些。这些可以是数据表中一个实际的、一个表达式,或者甚至是一个SELECT语句的结果,如代码清单1-14所示。     代码清单1-14  展现SELECT表各种可能情况的查询实例     SQL> select.customer_id, c.cust_first_name||''||c.cust_last_name,     .     当使用另外一个SELECT语句来产生结果中的一的值的时候,这个查询必须只能返回一的值。这种类型的子查询被称为标量子查询。尽管这可能是一个非常有用的语法,但需要牢记于心的是标量查询在结果集中的每一结果产生时都要执一遍。在某些情况下可以进优化以减少标量子查询的重复执,但更糟糕的场景是每一都需要标量子查询执。你可以想象如果你的结果集中有几千甚至上百万数据的时候所需要付出的查询代价!在后面的章节中我们还将回顾标量子查询并讨论如何更好地来使用它们。     在SELECT表中你还有可能用到的一个选项是DISTINCT子句。在例子中并没有使用它,但我想要简要地提及一下。DISTINCT子句用来在其他子句执完毕以后从结果集中去除重复的。     SELECT表执完以后,你就得到了最终的查询结果集。所剩的唯一需要做的事情,如果包含了的话,就是将查询结果集按照所需的顺序排序。     1.5.6  ORDER BY子句     ORDER BY子句用来对查询最终返回的结果集进排序。在本例中,需要按照orders_ct和customer_id进排序。orders_ct这一是通过GROUP BY子句中的COUNT聚合函数计算得到的值。如代码清单1-13中所示,有两个消费者的订单超过4个。由于这两个消费者的订单数都是5份,orders_ct这一的值是相同的,所以要由第二个排序来确定最终结果的显示顺序。如代码清单1-15中所示,该查询的最终经过排序的输出结果是按照customer_id排序的两数据集。     代码清单1-15  示例查询的最终输出     当输出结果需要排序的时候,Oracle必须在其他所有子句都执完之后按照指定的顺序对最终结果集进排序。需要排序的数据量大小是非常重要的。我这里所说的大小是指结果集中所包含的总字节数。你可以通过用数乘以每一的字节数来估计数据集的大小。每所包含的字节数通过将选择表中包含的每一的平均长度相加来确定。     上面的查询实例在选择表中仅需要出customer_id 和orders_ct两的值。我们可以估算每一输出值的字节数为10。在第6章中我将阐述从哪里能找到优化器所估计的值。因此,如果我们在结果集中只有两数据,排序的大小实际上是很小的,大约20字节。请记住这仅仅是估算,但这样的估算也是很重要的。     较小的排序会完全在内存中来实现,而较大的排序将不得不使用临时磁盘空间来完成。如你可能推断的那样,在内存中完成的排序比必须使用磁盘的排序要快。因此,当优化器估算排序数据的影响时,它必须要考虑排序数据集的大小,以此来调整如何能够以最有效的方法来获得查询的结果。一般来说,排序是查询过程中开销相当大的一个处理步骤,尤其是当返回结果集很大的时候。     1.6  INSERT语句     INSERT语句用来向表、分区或视图中添加。可以向单表或者多个表方法中添加数据。单表插入将会向一个表中插入一数据,这数据可以显式地出插入值也可以通过一个子查询来获取。多表插入将会向一个或多个表中插入,并且会通过子查询获取值来计算所插入的值。     1.6.1  单表插入     代码清单1-16中的第一个例子阐明了使用values子句实现的单表插入。每一的值都显式地输入。如果你要插入表中所定义的所有的值,那么表是可选的。但是,如果你只想提供部分的值,则必须在表中指明所需的名。好的做法是不管是不是需要插入所有的值,都把所有出来。这样做就像该语句的自述文件一样,并且也可以减少将来别人要插入一个新到表中的时候可能出现的错误。     代码清单1-16  单表插入     第二个例子阐述了通过子查询来实现插入。这是插入数据的一个非常灵活的选项。所写的子查询可以返回一或多数据。返回的每一都会用来生成需要插入的新值。根据你的需要这个子查询可以很简单也可以很复杂。在本例中,我们使用子查询实现了在现有薪水的基础上为每一位员工发放10%奖金的计算。事实上奖金表包含4,但在这个插入中我们只出了3个字段。comm这一在子查询中并没有占据一并且我们也没有将它包括在表中。因为我们没有包含这一,它的值将会是null。注意如果comm具有非空约束,那么可能已返回一个约束错误,语句的执也已失败。     1.6.2  多表插入     代码清单1-17所示的多表插入的例子阐明了一个子查询返回的数据是如何被用来插入多个表中的。我们从3个表开始:small_customers、medium_customers以及large_customers。我们想要按照每位消费者所下订单的总金额来将数据分别插入这些表。子查询将每一位消费者的order_total求和来确定该消费者的消费金额是小(所有订单的累加金额小于10 000美元)、中等(介于10 000美元与99 999.99美元之间)还是大(大于等于100 000美元),然后按照条件将这些插入对应的表中。     代码清单1-17  多表插入     注意INSERT关键字后面ALL子句的使用。当指定了ALL子句的时候,这个语句就会执无条件的多表插入。也就意味着每一个WHEN子句按照子查询所返回的每一来确定值而不管前一个条件的输出结果是什么。因此,你需要注意如何来指定每个条件。例如,如果我使用WHEN sum_orders < 100 000这个条件而不是像上面一样出范围,插入medium_customers表中的有可能也会插入small_customers表中。     你需要指明FIRST选项来实现每一个WHEN子句按照其出现在语句中的顺序评估,并且对于一个给定的子查询跳过接下来的WHEN子句评估。关键在于要记住哪一个选项能够更好地满足你的需要,ALL还是FIRST,然后使用最适合的选项。     1.7  UPDATE语句     UPDATE语句的作用是改变表中原有值。这个语句的语法由3部分组成:UPDATE、SET和WHERE。UPDATE子句用来指定要更新的表,SET子句用来指明哪些改变了以及调整的值,WHERE子句用来按条件筛选需要更新的。WHERE子句是可选的,如果忽略了这个子句的话,更新操作将针对指定表中的所有。     代码清单1-18出了几种UPDATE语句的不同写法。首先,我建立了一个employees表的副本,名称为employees2,然后我将执几个完成基本相同任务的不同更新操作:将90部门的员工工资增加10%。在例5中,commission_pct这一也进了更新。下面就是采用的不同方法。     例1:使用表达式更新一个单的值。     例2:通过子查询更新一个单的值。     例3:通过在WHERE子句中使用子查询确定要更新的数据来更新单的值。     例4:通过使用SELECT语句定义表及的值来更新表。     例5:通过子查询更新多。     代码清单1-18  UPDATE语句的例子     1.8  DELETE语句     DELETE语句用来从表中移除数据。该语句的语法结构由3部分组成:DELETE、FROM和WHERE。DELETE关键字是单独出的。除非你决定使用我们后面将会讨论到的提示(hint),没有其他选项与DELETE关键字相结合。FROM子句用来指定要从哪个表中删除数据。如代码清单1-19中的例子所示,这个表可以直接指定也可以通过子查询来确定。WHERE子句提供筛选条件有助于确定哪些是要删除的。如果忽略了WHERE子句,删除操作将删除指定表中的所有数据。     代码清单1-19展示出了DELETE语句的几种不同写法。注意,在这些例子中我使用了代码清单1-18中创建的employees2表。下面你将看到的就是这些不同的删除方法。     例1:使用WHERE子句中的筛选条件来从指定表中删除。     例2:使用FROM子句中的子查询来删除。     例3:使用WHERE子句中的子查询来从指定表中删除。     代码清单1-19  DELETE语句的例子     1.9  MERGE语句     MERGE语句具有按条件获取要更新或插入到表中的数据,然后从1个或多个源头对表进更新或者向表中插入两方面的能力。它最经常被用在数据仓库中来移动大量的数据,但它的应用不仅限于数据仓库环境下。这个语句提供的一个很大的附加值在于你可以很方便地把多个操作结合成一个。这就使你可以避免使用多个INSERT、UPDATE以及DELETE语句。并且,在本书后面的内容中你将看到,如果你避免去做那些不是必须做的事情,响应时间可能得到相应的改善。     MERGE语句的语法是:     为了说明MERGE语句的用法,代码清单1-20展示出了如何建立一个测试表,然后恰当地利用MERGE条件来向表中插入或更新。     代码清单1-20  MERGE语句例子     MERGE语句完成了下面这些事情。     ·插入了两(员工id 106和107)。     ·更新了一(员工id 105)。     ·删除了一(员工id 103)。     ·一保持不变(员工id 104)。     如果没有MERGE语句,你必须最少写3条不同的语句来完成同样的事情。     1.10  小结     正如你可以从到目前为止的例子中看出的,SQL语言提供了很多不同的选择来得到同样的结果集。你可能还注意到了一点就是这5个核心的SQL语句都可以使用类似的构造,例如子查询。关键是需要搞清楚在各种不同的使用场景下哪种构造是最高效的。我们将在本书后面的内容中阐述如何做到这一点。     如果你对本章的例子的理解有任何困难,请一定花点时间复习Beginning Oracle SQL或者Oracle文档中的SQL Reference Guide。在本书中接下来的部分我们假设你已经很好地理解了5个核心SQL语句的基本构造:SELECT、INSERT、UPDATE、DELETE和MERGE。
Ø 常用查询 MySQL结束符是“;”结束。 1、 显示所有数据库 show databases; 2、 删除数据库 drop database dbName; 3、 创建数据库 create database [if not exists] dbName; 中括号部分可选的,判断该数据不存在就创建 4、 切换、使用指定数据库 use dbName; 5、 显示当前使用数据库所有的表对象 show tables; 6、 显示表结构describe(desc) desc tableName; 7、 创建一张表 create table user ( --int 整型 uId int, --小数 uPrice decimal, --普通长度文本,default设置默认值 uName varchar(255) default ‘zhangsan’, --超长文本 uRemark text, --图片 uPhoto blob, --日期 uBirthday datetime ); 8、 子查询建表方法 部分名匹配模式: create table userInfo ( name varchar(20), sex char ) as select name, sex from user; 上面的名和子查询的名以及类型要对应 全部名模式: create table userInfo as select * from user; 直接将整个表的类型和数据备份到新表userInfo中 9、 添加表字段 添加单 alter table user add tel varchar(11) default ‘02012345678’; 添加多 alter table user add ( photo blob, birthday date ); 上面就同时增加了多字段 10、 修改表字段 修改tel alter table user modify tel varchar(15) default ‘02087654321’; 修改tel的位置,在第一显示 alter table user modify tel varchar(15) default '02087654321' first; 修改tel的位置,在指定之后显示 alter table user modify tel varchar(15) default '02087654321' after age; 注意:alter modify不支持一次修改多个,但是Oracle支持多修改 但是MySQL可以通过多个modify的方式完成: alter table user modify tel varchar(15) default '02087654321' first, modify name varchar(20) after tel; 11、 删除指定字段 alter table user drop photo; 12、 重命名表数据 表重命名 alter table user rename to users; 字段重命名 alter table users change name u_name varchar(10); alter table users change sex u_sex varchar(10) after u_name; 如果需要改变名建议使用change,如果需要改变数据类型和显示位置可以使用modify 13、 删除表 drop table users; drop删除表会删除表结构,表对象将不存在数据中;数据也不会存在;表内的对象也不存在,如:索引、视图、约束; truncate删除表 truncate都被当成DDL出来,truncate的作用就是删除该表里的全部数据,保留表结构。相当于DDL中的delete语句, 但是truncate比delete语句的速度要快得多。但是truncate不能带条件删除指定数据,只会删除所有的数据。如果删除的表有外键, 删除的速度类似于delete。但新版本的MySQL中truncate的速度比delete速度快。 Ø 约束 MySQL中约束保存在information_schema数据库的table_constraints中,可以通过该表查询约束信息; 约束主要完成对数据的检验,保证数据库数据的完整性;如果有相互依赖数据,保证该数据不被删除。 常用五类约束: not null:非空约束,指定某不为空 unique: 唯一约束,指定某和几组合的数据不能重复 primary key:主键约束,指定某的数据不能重复、唯一 foreign key:外键,指定该记录属于主表中的一条记录,参照另一条数据 check:检查,指定一个表达式,用于检验指定数据 MySQL不支持check约束,但可以使用check约束,而没有任何效果; 根据约束数据限制,约束可分为: 单约束:每个约束只约束一约束:每个约束约束多数据 MySQL中约束保存在information_schema数据库的table_constraints中,可以通过该表查询约束信息; 1、 not null约束 非空约束用于确保当前的值不为空值,非空约束只能出现在表对象的上。 Null类型特征: 所有的类型的值都可以是null,包括int、float等数据类型 空字符串“”是不等于null,0也不等于null create table temp( id int not null, name varchar(255) not null default ‘abc’, sex char null ) 上面的table加上了非空约束,也可以用alter来修改或增加非空约束 增加非空约束 alter table temp modify sex varchar(2) not null; 取消非空约束 alter table temp modify sex varchar(2) null; 取消非空约束,增加默认值 alter table temp modify sex varchar(2) default ‘abc’ null; 2、 unique 唯一约束是指定table的组合不能重复,保证数据的唯一性。虽然唯一约束不允许出现重复的值,但是可以为多个null 同一个表可以有多个唯一约束,多个组合的约束。在创建唯一约束的时候,如果不给唯一约束名称,就默认和名相同。 唯一约束不仅可以在一个表内创建,而且可以同时多表创建组合唯一约束。 MySQL会给唯一约束的上默认创建一个唯一索引; create table temp ( id int not null, name varchar(25), password varchar(16), --使用表级约束语法, constraint uk_name_pwd unique(name, password) ); 表示用户名和密码组合不能重复 添加唯一约束 alter table temp add unique(name, password); alter table temp modify name varchar(25) unique; 删除约束 alter table temp drop index name; 3、 primary key 主键约束相当于唯一约束+非空约束的组合,主键约束不允许重复,也不允许出现空值;如果的多组合的主键约束, 那么这些都不允许为空值,并且组合的值不允许重复。 每个表最多只允许一个主键,建立主键约束可以在级别创建,也可以在表级别上创建。MySQL的主键名总是PRIMARY, 当创建主键约束时,系统默认会在所在的组合上建立对应的唯一索引。 模式: create table temp( /*主键约束*/ id int primary key, name varchar(25) ); create table temp2( id int not null, name varchar(25), pwd varchar(15), constraint pk_temp_id primary key(id) ); 组合模式: create table temp2( id int not null, name varchar(25), pwd varchar(15), constraint pk_temp_id primary key(name, pwd) ); alter删除主键约束 alter table temp drop primary key; alter添加主键 alter table temp add primary key(name, pwd); alter修改为主键 alter table temp modify id int primary key; 设置主键自增 create table temp( id int auto_increment primary key, name varchar(20), pwd varchar(16) ); auto_increment自增模式,设置自增后在插入数据的时候就不需要给该插入值了。 4、 foreign key 约束 外键约束是保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系。 也就是说从表的外键值必须在主表中能找到或者为空。 当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据, 然后才可以删除主表的数据。还有一种就是级联删除子表数据。 注意:外键约束的参照,在主表中引用的只能是主键或唯一键约束的,假定引用的主表不是唯一的记录, 那么从表引用的数据就不确定记录的位置。同一个表可以有多个外键约束。 创建外键约束: 主表 create table classes( id int auto_increment primary key, name varchar(20) ); 从表 create table student( id int auto_increment, name varchar(22), constraint pk_id primary key(id), classes_id int references classes(id) ); 通常先建主表,然后再建从表,这样从表的参照引用的表才存在。 表级别创建外键约束: create table student( id int auto_increment primary key, name varchar(25), classes_id int, foreign key(classes_id) references classes(id) ); 上面的创建外键的方法没有指定约束名称,系统会默认给外键约束分配外键约束名称,命名为student_ibfk_n, 其中student是表名,n是当前约束从1开始的整数。 指定约束名称: create table student( id int auto_increment primary key, name varchar(25), classes_id int, /*指定约束名称*/ constraint fk_classes_id foreign key(classes_id) references classes(id) ); 多外键组合,必须用表级别约束语法: create table classes( id int, name varchar(20), number int, primary key(name, number) ); create table student( id int auto_increment primary key, name varchar(20), classes_name varchar(20), classes_number int, /*表级别联合外键*/ foreign key(classes_name, classes_number) references classes(name, number) ); 删除外键约束: alter table student drop foreign key student_ibfk_1; alter table student drop foreign key fk_student_id; 增加外键约束 alter table student add foreign key(classes_name, classes_number) referencesclasses(name, number); 自引用、自关联(递归表、树状表) create table tree( id int auto_increment primary key, name varchar(50), parent_id int, foreign key(parent_id) references tree(id) ); 级联删除:删除主表的数据时,关联的从表数据也删除,则需要在建立外键约束的后面增加on deletecascade 或on delete set null,前者是级联删除,后者是将从表的关联的值设置为null。 create table student( id int auto_increment primary key, name varchar(20), classes_name varchar(20), classes_number int, /*表级别联合外键*/ foreign key(classes_name, classes_number) references classes(name, number) on deletecascade ); 5、 check约束 MySQL可以使用check约束,但check约束对数据验证没有任何作用。 create table temp( id int auto_increment, name varchar(20), age int, primary key(id), /*check约束*/ check(age > 20) ); 上面check约束要求age必须大于0,但没有任何作用。但是创建table的时候没有任何错误或警告。 Ø 索引 索引是存放在模式(schema)中的一个数据库对象,索引的作用就是提高对表的检索查询速度, 索引是通过快速访问的方法来进快速定位数据,从而减少了对磁盘的读写操作。 索引是数据库的一个对象,它不能独立存在,必须对某个表对象进依赖。 提示:索引保存在information_schema数据库里的STATISTICS表中。 创建索引方式: 自动:当表上定义主键约束、唯一、外键约束时,该表会被系统自动添加上索引。 手动:手动在相关表或上增加索引,提高查询速度。 删除索引方式: 自动:当表对象被删除时,该表上的索引自动被删除 手动:手动删除指定表对象的相关上的索引 索引类似于书籍的目录,可以快速定位到相关的数据,一个表可以有多个索引。 创建索引: create index idx_temp_name on temp(name); 组合索引: create index idx_temp_name$pwd on temp(name, pwd); 删除索引: drop index idx_temp_name on temp; Ø 视图 视图就是一个表或多个表的查询结果,它是一张虚拟的表,因为它并不能存储数据。 视图的作用、优点: 限制对数据的访问 让复杂查询变得简单 提供数据的独立性 可以完成对相同数据的不同显示 创建、修改视图 create or replace view view_temp as select name, age from temp; 通常我们并不对视图的数据做修改操作,因为视图是一张虚拟的表,它并不存储实际数据。如果想让视图不被修改,可以用with check option来完成限制。 create or replace view view_temp as select * from temp with check option; 修改视图: alter view view_temp as select id, name from temp; 删除视图: drop view view_temp; 显示创建语法: show create view v_temp; Ø DML语句 DML主要针对数据库表对象的数据而言的,一般DML完成: 插入新数据 修改已添加的数据 删除不需要的数据 1、 insert into 插入语句 insert into temp values(null, ‘jack’, 25); 主键自增可以不插入,所以用null代替 指定 insert into temp(name, age) values(‘jack’, 22); 在表面后面带括号,括号中写名,values中写指定名的值即可。当省略名就表示插入全部数据, 注意插入值的顺序顺序需要保持一致。 Set方式插入,也可以指定 insert into temp set id = 7, name = 'jason'; MySQL中外键的table的外键引用可以插入数据可以为null,不参照主表的数据。 使用子查询插入数据 insert into temp(name) select name from classes; 多插入 insert into temp values(null, ‘jack’, 22), (null, ‘jackson’ 23); 2、 update 修改语句 update主要完成对数据的修改操作,可以修改一条或多条数据。修改多条或指定条件的数据,需要用where条件来完成。 修改所有数据 update temp set name = ‘jack2’; 所有的数据的name会被修改,如果修改多用“,”分开 update temp set name = ‘jack’, age = 22; 修改指定条件的记录需要用where update temp set name = ‘jack’ where age > 22; 3、 delete 删除语句 删除table中的数据,可以删除所有,带条件可以删除指定的记录。 删除所有数据 delete from temp; 删除指定条件数据 delete from temp where age > 20; Ø select 查询、function 函数 select查询语句用得最广泛、功能也最丰富。可以完成单条记录、多条记录、单表、多表、子查询等。 1、 查询某张表所有数据 select * from temp; *代表所有,temp代表表名,不带条件就查询所有数据 2、 查询指定和条件的数据 select name, age from temp where age = 22; 查询name和age这两,age 等于22的数据。 3、 对查询的数据进运算操作 select age + 2, age / 2, age – 2, age * 2 from temp where age – 2 > 22; 4、 concat函数,字符串连接 select concat(name, ‘-eco’) from temp; concat和null进连接,会导致连接后的数据成为null 5、 as 对重命名 select name as ‘名称’ from temp; as也可以省略不写,效果一样 如果重命名的名出现特殊字符,如“‘”单引号,那就需要用双引号引在外面 select name as “名’称” from temp; 6、 也可以给table去别名 select t.name Name from temp as t; 7、 查询常量 类似于SQL Server select 5 + 2; select concat('a', 'bbb'); 8、 distinct 去掉重复数据 select distinct id from temp; 多将是组合的重复数据 select distinct id, age from temp; 9、 where 条件查询 大于>、大于等于>=、小于<、小于等于<=、等于=、不等于<> 都可以出现在where语句中 select * from t where a > 2 or a >= 3 or a < 5 or a <= 6 or a = 7 or a <> 0; 10、 and 并且 select * from temp where age > 20 and name = ‘jack’; 查询名称等于jack并且年龄大于20的 11、 or 或者 满足一个即可 select * from tmep where name = ‘jack’ or name = ‘jackson’; 12、 between v and v2 大于等于v且小于等于v2 select * form temp where age between 20 and 25; 13、 in 查询 可以多个条件 类似于or select * from temp where id in (1, 2, 3); 查询id在括号中出现的数据 14、 like 模糊查询 查询name以j开头的 select * from temp where name like ‘j%’; 查询name包含k的 select * from temp where name like ‘%k%’; escape转义 select * from temp where name like ‘/_%’ escape ‘/’; 指定/为转义字符,上面的就可以查询name中包含“_”的数据 15、 is null、is not null 查询为null的数据 select * from temp where name is null; 查询不为null的数据 select * from temp where name is not null; 16、 not select * from temp where not (age > 20); 取小于等于20的数据 select * from temp where id not in(1, 2); 17、 order by 排序,有desc、asc升序、降序 select * from temp order by id; 默认desc排序 select * from temp order by id asc; 多组合 select * from temp order by id, age; Ø function 函数 函数的作用比较大,一般多用在select查询语句和where条件语句之后。按照函数返回的结果, 可以分为:多函数和单函数;所谓的单函数就是将每条数据进独立的计算,然后每条数据得到一条结果。 如:字符串函数;而多函数,就是多条记录同时计算,得到最终只有一条结果记录。如:sum、avg等 多函数也称为聚集函数、分组函数,主要用于完成一些统计功能。MySQL的单函数有如下特征: 单函数的参数可以是变量、常量或数据。单函数可以接受多个参数,但返回一个值。 单函数就是它会对每一单独起作用,每一(可能包含多个参数)返回一个结果。 单函数可以改变参数的数据类型。单函数支持嵌套使用:内层函数的返回值是外层函数的参数。 单函数可以分为: 类型转换函数; 位函数; 流程控制语句; 加密解密函数; 信息函数 单函数 1、 char_length字符长度 select char_length(tel) from user; 2、 sin函数 select sin(age) from user; select sin(1.57); 3、 添加日期函数 select date_add('2010-06-21', interval 2 month); interval是一个关键字,2 month是2个月的意思,2是数值,month是单位 select addDate('2011-05-28', 2); 在前面的日期上加上后面的天数 4、 获取当前系统时间、日期 select curdate(); select curtime(); 5、 加密函数 select md5('zhangsan'); 6、 Null 处理函数 select ifnull(birthday, 'is null birthday') from user; 如果birthday为null,就返回后面的字符串 select nullif(age, 245) from user; 如果age等于245就返回null,不等就返回age select isnull(birthday) from user; 判断birthday是否为null select if(isnull(birthday), 'birthday is null', 'birthday not is null') from user; 如果birthday为null或是0就返回birthday is null,否则就返回birthday not is null;类似于三目运算符 7、 case 流程函数 case函数是一个流程控制函数,可以接受多个参数,但最终只会返回一个结果。 select name, age, (case sex when 1 then '男' when 0 then '女' else '火星人' end ) sex from user; 组函数 组函数就是多函数,组函数是完成一或多结果集的运算,最后返回一个结果,而不是每条记录返回一个结果。 1、 avg平均值运算 select avg(age) from user; select avg(distinct age) from user; 2、 count 记录条数统计 select count(*), count(age), count(distinct age) from user; 3、 max 最大值 select max(age), max(distinct age) from user; 4、 min 最小值 select min(age), min(distinct age) from user; 5、 sum 求和、聚和 select sum(age), sum(distinct age) from user; select sum(ifnull(age, 0)) from user; 6、 group by 分组 select count(*), sex from user group by sex; select count(*) from user group by age; select * from user group by sex, age; 7、 having进条件过滤 不能在where子句中过滤组,where子句仅用于过滤。过滤group by需要having 不能在where子句中用组函数,having中才能用组函数 select count(*) from user group by sex having sex <> 2; Ø 多表查询和子查询 数据库的查询功能最为丰富,很多时候需要用到查询完成一些事物,而且不是单纯的对一个表进操作。而是对多个表进联合查询, MySQL中多表连接查询有两种规范,较早的SQL92规范支持,如下几种表连接查询: 等值连接 非等值连接 外连接 广义笛卡尔积 SQL99规则提供了可读性更好的多表连接语法,并提供了更多类型的连接查询,SQL99支持如下几种多表连接查询: 交叉连接 自然连接 使用using子句的连接 使用on子句连接 全部连接或者左右外连接 SQL92的连接查询 SQL92的连接查询语法比较简单,多将多个table放置在from关键字之后,多个table用“,”隔开; 连接的条件放在where条件之后,与查询条件直接用and逻辑运算符进连接。如果条件中使用的是相等, 则称为等值连接,相反则称为非等值,如果没有任何条件则称为广义笛卡尔积。 广义笛卡尔积:select s.*, c.* from student s, classes c; 等值:select s.*, c.* from student s, classes c where s.cid = c.id; 非等值:select s.*, c.* from student s, classes c where s.cid <> c.id; select s.*, c.name classes from classes c, student s where c.id = s.classes_id ands.name is not null; SQL99连接查询 1、交叉连接cross join,类似于SQL92的笛卡尔积查询,无需条件。如: select s.*, c.name from student s cross join classes c; 2、自然连接 natural join查询,无需条件,默认条件是将2个table中的相同字段作为连接条件,如果没有相同字段,查询的结果就是空。 select s.*, c.name from student s natural join classes c; 3、using子句连接查询:using的子句可以是一或多显示的指定两个表中同名作为连接条件。 如果用natural join的连接查询,会把所有的相同字段作为连接查询。而using可以指定相同及个数。 select s.*, c.name from student s join classes c using(id); 4、 join … on连接查询,查询条件在on中完成,每个on语句只能指定一个条件。 select s.*, c.name from student s join classes c on s.classes_id = c.id; 5、 左右外连接:3种外连接,left [outer] join、right [outer] join,连接条件都是通过用on子句来指定,条件可以等值、非等值。 select s.*, c.name from student s left join classes c on s.classes_id = c.id; select s.*, c.name from student s right join classes c on s.classes_id = c.id; 子查询 子查询就是指在查询语句中嵌套另一个查询,子查询可以支持多层嵌套。子查询可以出现在2个位置: from关键字之后,被当做一个表来进查询,这种用法被称为内视图,因为该子查询的实质就是一个临时视图 出现在where条件之后作为过滤条件的值 子查询注意点: 子查询用括号括起来,特别情况下需要起一个临时名称 子查询当做临时表时(在from之后的子查询),可以为该子查询起别名,尤其是要作为前缀来限定数据名时 子查询用作过滤条件时,将子查询放在比较运算符的右边,提供可读性 子查询作为过滤条件时,单子查询使用单运算符,多子查询用多运算符 将from后面的子查询当做一个table来用: select * from (select id, name from classes) s where s.id in (1, 2); 当做条件来用: select * from student s where s.classes_id in (select id from classes); select * from student s where s.classes_id = any (select id from classes); select * from student s where s.classes_id > any (select id from classes); Ø 操作符和函数 1、 boolean只判断 select 1 is true, 0 is false, null is unknown; select 1 is not unknown, 0 is not unknown, null is not unknown; 2、 coalesce函数,返回第一个非null的值 select coalesce(null, 1); select coalesce(1, 1); select coalesce(null, 1); select coalesce(null, null); 3、 当有2个或多个参数时,返回最大的那个参数值 select greatest(2, 3); select greatest(2, 3, 1, 9, 55, 23); select greatest('D', 'A', 'B'); 4、 Least函数,返回最小值,如果有null就返回null值 select least(2, 0); select least(2, 0, null); select least(2, 10, 22.2, 35.1, 1.1); 5、 控制流函数 select case 1 when 1 then 'is 1' when 2 then 'is 2' else 'none' end; select case when 1 > 2 then 'yes' else 'no' end; 6、 ascii字符串函数 select ascii('A'); select ascii('1'); 7、 二进制函数 select bin(22); 8、 返回二进制字符串长度 select bit_length(11); 9、 char将值转换成字符,小数取整四舍五入 select char(65); select char(65.4); select char(65.5); select char(65.6); select char(65, 66, 67.4, 68.5, 69.6, '55.5', '97.3'); 10、 using改变字符集 select charset(char(0*65)), charset(char(0*65 using utf8)); 11、 得到字符长度char_length,character_length select char_length('abc'); select character_length('eft'); 12、 compress压缩字符串、uncompress解压缩 select compress('abcedf'); select uncompress(compress('abcedf')); 13、 concat_ws分隔字符串 select concat_ws('#', 'first', 'second', 'last'); select concat_ws('#', 'first', 'second', null, 'last'); Ø 事务处理 动作 开始事务:start transaction 提交事务:commit 回滚事务:rollback 设置自动提交:set autocommit 1 | 0 atuoCommit系统默认是1立即提交模式;如果要手动控制事务,需要设置set autoCommit 0; 这样我们就可以用commit、rollback来控制事务了。 在一段语句块中禁用autocommit 而不是set autocommit start transaction; select @result := avg(age) from temp; update temp set age = @result where id = 2; select * from temp where id = 2;//值被改变 rollback;//回滚 select * from temp where id = 2;//变回来了 在此期间只有遇到commit、rollback,start Transaction的禁用autocommit才会结束。然后就恢复到原来的autocommit模式; 不能回滚的语句 有些语句不能被回滚。通常,这些语句包括数据定义语言(DDL)语句,比如创建或取消数据库的语句, 和创建、取消或更改表或存储的子程序的语句。 您在设计事务时,不应包含这类语句。如果您在事务的前部中发布了一个不能被回滚的语句, 则后部的其它语句会发生错误,在这些情况下,通过发布ROLLBACK语句不能 回滚事务的全部效果。 一些操作也会隐式的提交事务 如alter、create、drop、rename table、lock table、set autocommit、starttransaction、truncate table 等等, 在事务中出现这些语句也会提交事务的 事务不能嵌套事务 事务的保存点 Savepoint pointName/Rollback to savepoint pointName 一个事务可以设置多个保存点,rollback可以回滚到指定的保存点,恢复保存点后面的操作。 如果有后面的保存点和前面的同名,则删除前面的保存点。 Release savepoint会删除一个保存点,如果在一段事务中执commit或rollback,则事务结束,所以保存点删除。 Set Transaction设计数据库隔离级别 SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } 本语句用于设置事务隔离等级,用于下一个事务,或者用于当前会话。 在默认情况下,SET TRANSACTION会为下一个事务(还未开始)设置隔离等级。 如果您使用GLOBAL关键词,则语句会设置全局性的默认事务等级, 用于从该点以后创建的所有新连接。原有的连接不受影响。使用SESSION关键测可以设置默认事务等级, 用于对当前连接执的所有将来事务。 默认的等级是REPEATABLE READ全局隔离等级。 Ø 注释 select 1+1; # 单注释 select 1+1; -- 单注释 select 1 /* 多注释 */ + 1; Ø 基本数据类型操作 字符串 select 'hello', '"hello"', '""hello""', 'hel''lo', '/'hello'; select "hello", "'hello'", "''hello''", "hel""lo", "/"hello"; /n换 select 'This/nIs/nFour/nLines'; /转义 select 'hello / world!'; select 'hello /world!'; select 'hello // world!'; select 'hello /' world!'; Ø 设置数据库mode模式 SET sql_mode='ANSI_QUOTES'; create table t(a int); create table "tt"(a int); create table "t""t"(a int); craate talbe tab("a""b" int); Ø 用户变量 set @num1 = 0, @num2 = 2, @result = 0; select @result := (@num1 := 5) + @num2 := 3, @num1, @num2, @result; Ø 存储过程 创建存储过程: delimiter // create procedure get(out result int) begin select max(age) into result from temp; end// 调用存储过程: call get(@temp); 查询结果: select @temp; 删除存储过程: drop procedure get; 查看存储过程创建语句: show create procedure get; select…into 可以完成单记录的赋值: create procedure getRecord(sid int) begin declare v_name varchar(20) default 'jason'; declare v_age int; declare v_sex bit; select name, age, sex into v_name, v_age, v_sex from temp where id = sid; select v_name, v_age, v_sex; end; call getRecord(1); Ø 函数 函数类似于存储过程,只是调用方式不同 例如:select max(age) from temp; 创建函数: create function addAge(age int) returns int return age + 5; 使用函数: select addAge(age) from temp; 删除函数: drop function if exists addAge; drop function addAge; 显示创建语法: show create function addAge; Ø 游标 声明游标:declare cur_Name cursor for select name from temp; 打开游标:open cur_Name; Fetch游标:fetch cur_Name into @temp; 关闭游标:close cur_Name; 示例: CREATE PROCEDURE cur_show() BEGIN DECLARE done INT DEFAULT 0; DECLARE v_id, v_age INT; DECLARE v_name varchar(20); DECLARE cur_temp CURSOR FOR SELECT id, name, age FROM temp; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; OPEN cur_temp; REPEAT FETCH cur_temp INTO v_id, v_name, v_age; IF NOT done THEN IF isnull(v_name) THEN update temp set name = concat('test-json', v_id) where id = v_id; ELSEIF isnull(v_age) THEN update temp set age = 22 where id = v_id; END IF; END IF; UNTIL done END REPEAT; CLOSE cur_temp; END Ø 触发器 触发器分为insert、update、delete三种触发器事件类型 还有after、before触发时间 创建触发器: create trigger trg_temp_ins before insert on temp for each row begin insert into temp_log values(NEW.id, NEW.name); end// 删除触发器: drop trigger trg_temp_ins

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧