Oracle的sql详细总结2

继上一篇说明orcal1点击打开链接,现对oracle2讲说明:

一、oracle中的子查询

SQL> --查询工资比SCOTT高的员工信息

  1  select *
  2  from emp
  3  where sal > (select sal
  4               from emp
  5              where ename='SCOTT')

对子查询的10点说明:

SQL> /*
SQL> 注意的问题
SQL> 1. 括号
SQL> 2. 合理的书写风格
SQL> 3. 可以在主查询的where select having from后面放置子查询
SQL> 4. 不可以在group by后面放置子查询
SQL> 5. 强调from后面的子查询
SQL> 6. 主查询和子查询可以不是同一张表;只要子查询返回的结果主查询可以使用即可
SQL> 7. 一般不在子查询中排序;但在Top-N分析问题中,必须对子查询排序
SQL> 8. 一般先执行子查询,再执行主查询;但相关子查询例外
SQL> 9. 单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
SQL> 10. 子查询中的null
SQL> */


7. 一般不在子查询中排序;但在Top-N分析问题中,必须对子查询排序

如下的top分析问题中:


SQL> select rownum ,empno,ename ,sal from (select * from emp order by sal desc) where rownum<=3;


    ROWNUM      EMPNO ENAME             SAL
---------- ---------- ---------- ----------
         1       7839 KING             5000
         2       7788 SCOTT            3000
         3       7902 FORD             30003

--rownum 行号 oracle中的伪列

SQL> /*
SQL> 关于行号
SQL> 1. rownum 永远按照默认的顺序生成
SQL> 2. rownum只能使用< <=; 不能使用> >=
SQL> */

oracle的分页功能就是借助oracle的rownum伪列来完成的;

--oracle的分页
select * from 
(select rownum r,empno,ename ,sal 
from (select * from emp order by sal desc) e1
where rownum<=8) e2
 where e2.r>=5

这里的r>=5可以使用的原因是,这时的rownum已经是e2表的一个字段了,而不再是临时表创建的伪列行号;

对于rownum的默认生成顺序的说明:

是因为rownum是自动的由oracle创建的临时表的;

oralce创建三个表:

1、标准表;

2、临时表;

 --临时表:create global temporary table ******
SQL> --特点:当事务或者会话结束的时候,表中的数据自动删除

所以,临时表创建之后,不是对标准表进行操作后的样子,而是临时的自动创建的一个临时表,来显示查询到的数据;

3、索引表;


SQL> 8. 一般先执行子查询,再执行主查询;但相关子查询例外


 
--查询出员工表中,员工的薪水大于本部门的平均薪水的员工的信息
select e.* ,ee.avgsal from emp e,(select deptno, avg(sal) avgsal from emp group by deptno) ee 
where e.deptno=ee.deptno and e.sal>ee.avgsal


用上面的例子说明,相关子查询:

 --相关子查询:将主查询中的某些值作为参数传递给子查询
SQL> select empno,ename,sal,(select avg(sal) from emp where deptno=e.deptno) avgsal
  2  from emp e
  3  where sal > (select avg(sal) from emp where deptno=e.deptno);

这里的主查询的部门号作为参数,传递给了子查询的条件;这样就先执行了,主查询语句,把主查询的参数传递给子查询后,完整执行句子的执行过程;作为了解;

SQL> 9. 单行子查询只能使用单行操作符多行子查询只能使用多行操作符

单行子查询,指的是子查询返回单个字段的值,只能够使用单行的操作符,例如:=,<,>......

多行子查询,指的是子查询返回多个值,这时不能够使用单行的操作符来接受,只能够使用多行操作符,例如:in()  ,not in()



SQL> --any 和集合中任意一个值比较
SQL> --查询工资比30号部门任意一个员工高的员工信息

   select *
   from emp
   where sal > any (select sal from emp where deptno=30)

相当于: select *
  from emp
  where sal > (select min(sal) from emp where deptno=30)


--all: 和集合中的所有值比较
SQL>  --查询工资比30号部门所有员工高的员工信息
SQL> select *
   from emp
    where sal > all (select sal from emp where deptno=30);

相当于:

   select *
   from emp
   where sal > (select max(sal) from emp where deptno=30)



SQL> 10. 子查询中的null

10.1、单行子查询中的null值问题:

例如:



10.2、多行子查询中的null问题:

由于not in (a,b,null)中不可以有null值的原因;


二、oracle中的集合运算

1、几种交集运算:


2、利用集合运算应该注意的问题:

SQL> /*
SQL>  注意的问题:
SQL> 1.  参与运算的各个集合必须列数相同  且类型一致
SQL> 2.  采用第一个集合表头作为最后表头
SQL> 3.   order by 永远在最后
SQL> 4.  括号可以改变执行的顺序
SQL> */

SQL>  select deptno,job,sum(sal) from emp group by deptno,job
     union
     select deptno,to_char(null),sum(sal) from emp group by deptno
     union
     select to_number(null),to_char(null),sum(sal) from emp;

上面的sql的作用和下面sql的作用是相同的(group by 的增强作用):

SQL>  select deptno,job,sum(sal) from emp group by rollup(deptno,job);

2、下面的交集运算和差集运算和上面的并集运算的规则都是一样的;

三、oracle中的处理数据

1、sql语句的几种类型:

SQL> /*
SQL> SQL的类型
SQL> 1. DML(Data  Manipulation Language 数据操作语言): insert update delete select
SQL> 2. DDL(Data Definition Language 数据定义语言): create/alter/drop/truncate table
SQL>                                                create/drop view,sequence,index,synonym(同义词)
SQL> 3. DCL(Data Control Language 数据控制语言): grant(授权) revoke(撤销权限)
SQL> */

2、数据库的DML语句就不多讲了;

在这里主要说明一下,数据库的操作语言中的delete语句;

/*
SQL> delete 和truncate区别
SQL> 1. delete 逐条删除,truncate先删除表,再重建
SQL> 2.****delete是DML(可以回滚) truncate是DDL(不可以回滚)
SQL> 3. delete 不会释放空间;truncate会
SQL> 4. delete会产生碎片  truncate不会
SQL> 5. delete可以闪回(flashback) truncate不可以
SQL> */

2.2、oracle中的事务:

SQL> /*
SQL> Oracle中的事务
SQL> 1. 起始标志:事务中第一题DML语句
SQL> 2. 结束标志: 提交: 显式 commit
SQL>                      隐式 正常退出exit,DDL,DCL
SQL>               回滚   显式 rollback
SQL>                      隐式 非正常退出,掉电,宕机
SQL> */

注意的是:oracle中的事务是自动开启的;

                 mysql中的事务需要手动开启的;

2.21、oracle中事务的控制


SQL> create table testsavepoint
  2  (tid number,tname varchar2(20));
SQL> set feedback on
SQL> insert into testsavepoint values(1,'Tom');

已创建 1 行。

SQL> insert into testsavepoint values(2,'Mary');

已创建 1 行。

SQL> --定义保存点
SQL> savepoint a;

保存点已创建。

SQL> select * from testsavepoint;

       TID TNAME                                                                
---------- --------------------                                                 
         1 Tom                                                                  
         2 Mary                                                                 

已选择 2 行。

SQL> insert into testsavepoint values(3,'Mikd');

已创建 1 行。

SQL>  select * from testsavepoint;

       TID TNAME                                                                
---------- --------------------                                                 
         1 Tom                                                                  
         2 Mary                                                                 
         3 Mikd                                                                 

已选择 3 行。

SQL> rollback to savepoint a;

回退已完成。

SQL> select * from testsavepoint;

       TID TNAME                                                                
---------- --------------------                                                 
         1 Tom                                                                  
         2 Mary                                                                 

已选择 2 行。

SQL> commit;

提交完成。

2.22、oracle中的隔离机制



还有一种事务级别:

SQL> set transaction read only;
事务处理集。

意思是:只能够读的事务设置;

四、oracle中数据库的对象

oracle的DDL语句:


(一)、表的创建和管理

表的理解:表是数据库存储数据的物理层面的存储的概念思想;

oracle中的数据类型:


1、表的创建

 创建表有两种形式:

1.1、SQL> create table test1
   (tid number,
     tname varchar2(20));

1.2、通过子查询创建表

SQL> --创建表,保存20号部门的员工
SQL> create table emp20
    as
    select * from emp where deptno=20;

这里说明的是,当where后的条件为真,这时在创建表的同时,还会插入对应放入数据,如果where后的条件为假,只创建这个表的类型结构;

2、表的修改

--修改表:追加新列  修改列 删除列 重命名列 重命名表

查询表的结构:desc test1

SQL> desc test1
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 TID                                                NUMBER
 TNAME                                              VARCHAR2(20)
为表test1添加photo这一列
SQL> alter table test1 add photo blob;

表已更改。

SQL> desc test1
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 TID                                                NUMBER
 TNAME                                              VARCHAR2(20)
 PHOTO                                              BLOB
把表test1的tname长度修改成40
SQL> alter table test1 modify tname varchar2(40);

表已更改。
把表test1的photo字段去掉
SQL> alter table test1 drop column photo;

表已更改。
把表test1的tname给成username
SQL> alter table test1 rename column tname to username;

表已更改。

SQL> desc test1
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 TID                                                NUMBER
 USERNAME                                           VARCHAR2(40)
把表test1改成表test3
SQL> rename test1 to test3;

表已重命名。

3、表的删除

SQL> --删除表
SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID                               
------------------------------ ------- ----------                               
DEPT                           TABLE                                            
EMP                            TABLE                                            
BONUS                          TABLE                                            
SALGRADE                       TABLE                                            
TESTSAVEPOINT                  TABLE                                            
EMP10                          TABLE                                            
TESTDELETE                     TABLE                                            
TEST2                          TABLE                                            
EMP20                          TABLE                                            
EMPINFO                        TABLE                                            
TEST3                          TABLE                                            

已选择 11 行。

SQL> drop table TESTDELETE;

表已删除。

SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID                               
------------------------------ ------- ----------                               
DEPT                           TABLE                                            
EMP                            TABLE                                            
BONUS                          TABLE                                            
SALGRADE                       TABLE                                            
TESTSAVEPOINT                  TABLE                                            
EMP10                          TABLE                                            
BIN$lnBWiZXBQhqq9TNWZh8hMw==$0 TABLE                                            
TEST2                          TABLE                                            
EMP20                          TABLE                                            
EMPINFO                        TABLE                                            
TEST3                          TABLE                                            

已选择 11 行。

SQL> --Oracle的回收站
SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME          
---------------- ------------------------------ ------------ -------------------
TESTDELETE       BIN$lnBWiZXBQhqq9TNWZh8hMw==$0 TABLE        2014-12-27:16:05:42
SQL> purge  recyclebin;

回收站已清空。

SQL> select * from TESTSAVEPOINT;

       TID TNAME                                                                
---------- --------------------                                                 
         1 Tom                                                                  
         2 Mary                                                                 

已选择 2 行。

SQL> drop table TESTSAVEPOINT;

表已删除。

SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME          
---------------- ------------------------------ ------------ -------------------
TESTSAVEPOINT    BIN$B/vbnKyvSiCNnSufkw5+ng==$0 TABLE        2014-12-27:16:08:49
SQL> select * from TESTSAVEPOINT;
select * from TESTSAVEPOINT
              *
第 1 行出现错误: 
ORA-00942: 表或视图不存在 


SQL> select * from BIN$B/vbnKyvSiCNnSufkw5+ng==$0;
select * from BIN$B/vbnKyvSiCNnSufkw5+ng==$0
                   *
第 1 行出现错误: 
ORA-00933: SQL 命令未正确结束 


SQL> select * from "BIN$B/vbnKyvSiCNnSufkw5+ng==$0";

       TID TNAME                                                                
---------- --------------------                                                 
         1 Tom                                                                  
         2 Mary                                                                 

已选择 2 行。
上面的主要说明的是:在oracle中,删除表就相当于把该表放到了回收站的情况;

4、创建表的约束问题:


SQL> create table test4
  2  (tid number,
  3   tname varchar2(20),
  4   gender varchar2(2) check (gender in ('男','女')),
  5   sal number check (sal > 0)
  6  );

表已创建。

SQL> insert into test4 values(1,'Tom','男',1000);

已创建 1 行。

SQL> insert into test4 values(2,'Tom','啊',1000);
insert into test4 values(2,'Tom','啊',1000)
*
第 1 行出现错误: 
ORA-02290: 违反检查约束条件 (SCOTT.SYS_C005420) 


SQL> create table student
  2  (
  3   sid number constraint student_pk primary key,
  4   sname varchar2(20) constraint student_name_notnull not null,
  5   gender varchar2(2) constraint student_gender check (gender in ('男','女')),
  6   email varchar2(40) constraint student_email_unique unique
  7                      constraint student_email_notnull not null,
  8   deptno number constraint student_fk references dept(deptno) on delete set null
  9  );

表已创建。

SQL> insert into student values(1,'Tom','男','[email protected]',10);

已创建 1 行。

SQL> insert into student values(2,'Mike','男','[email protected]',10);
insert into student values(2,'Mike','男','[email protected]',10)
*
第 1 行出现错误: 
ORA-00001: 违反唯一约束条件 (SCOTT.STUDENT_EMAIL_UNIQUE) 

(二)、视图view

1、对视图的认识:


视图,一种建立在基础表的基础上,用来逻辑存储数据的视图,以供简化查询来实现存在的意义;


2、视图的创建(视图的创建和表的创建几乎是一样的)


SQL> --视图
SQL> create view empinfoview
    as
    select e.empno,e.ename,e.sal,e.sal*12 annlsa,d.dname
    from emp e,dept d
    where e.deptno=d.deptno;

3、由于视图的主要作用是用来创建方便查询的作用(查询视图、修改视图、删除视图都和表一样的),这里就不在赘述;

例如:查询视图:select * from empinfoview

(三)、序列sequence

1、认识序列


序列,时间上就是一个可变的存储数据的数组,默认长度为20;

2、序列 的作用是:通常作为一个表的主键;

3、序列的创建:




序列实际上在取数值的时候是通过指针来取数值的,由于:


所以,通常在使用的时候,使用nextvalue;

SQL> --序列 sequence
SQL> create sequence myseq;

序列已创建。

SQL> create table testseq
  2  (tid number,
  3   tname varchar2(20));

表已创建。

SQL> select myseq.currval from dual;
select myseq.currval from dual
       *
第 1 行出现错误: 
ORA-08002: 序列 MYSEQ.CURRVAL 尚未在此会话中定义 


SQL> select myseq.nextval from dual;

   NEXTVAL                                                                      
----------                                                                      
         1                                                                      

已选择 1 行。

SQL> select myseq.currval from dual;

   CURRVAL                                                                      
----------                                                                      
         1                                                                      

已选择 1 行。

SQL> insert into testseq(tid,tname) values(myseq.nextval,'aaaa');

已创建 1 行。

SQL> /

已创建 1 行。

SQL> /

已创建 1 行。

SQL> /

已创建 1 行。

SQL> commit;

提交完成。

SQL> select * from testseq;

       TID TNAME                                                                
---------- --------------------                                                 
         2 aaaa                                                                 
         3 aaaa                                                                 
         4 aaaa                                                                 
         5 aaaa                                                                 

已选择 4 行。

SQL> insert into testseq(tid,tname) values(myseq.nextval,'aaaa');

已创建 1 行。

SQL> /

已创建 1 行。

SQL> rollback;

回退已完成。

SQL> insert into testseq(tid,tname) values(myseq.nextval,'aaaa');

已创建 1 行。

SQL> select * from testseq;

       TID TNAME                                                                
---------- --------------------                                                 
         2 aaaa                                                                 
         3 aaaa                                                                 
         4 aaaa                                                                 
         5 aaaa                                                                 
         8 aaaa                                                                 

已选择 5 行。

(四)、索引index

1、对索引 的认识:

实际上索引就像一本书的目录,为了找说中的某个章节的内容,直接打开该书,通过目录找该章节的内容比一页一页额的查找快的多,这个通过数的目录查找该章节 的内容的过程就是通过索引查找数据库中的数据的一种快速查找数据的方式;创建书的目录的过程就是创建索引的过程;

2、oracle中的索引




1、索引的简单原理结构图:


2、对索引的查询,可以使用数据字典来查询:


3、删除索引:


SQL> --索引 index

--给emp表的的deptno创建索引
SQL> create index myindex
         on emp(deptno);
索引已创建。


SQL> --通过得到SQL的执行计划,可以确认是否查询了索引

(五)、同义词synonym 

1、对同义词的认识:

同义词就是相当于别名意义,可以给表起一个别名,可以给视图起一个别名......

SQL> --同义词 (别名)
SQL> show user
USER 为 "SCOTT"
SQL> select count(*) from hr.employees;
select count(*) from hr.employees
                        *
第 1 行出现错误: 
ORA-00942: 表或视图不存在 


SQL> select count(*) from hr.employees;

  COUNT(*)                                                                      
----------                                                                      
       107                                                                      

已选择 1 行。

SQL> --为hr.employees起别名  ---> 同义词
SQL> create synonym hremp for hr.employees;
create synonym hremp for hr.employees
*
第 1 行出现错误: 
ORA-01031: 权限不足 


SQL> /

同义词已创建。

SQL> select count(*) from hremp;

  COUNT(*)                                                                      
----------                                                                      
       107                                                                      

已选择 1 行。

SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID                               
------------------------------ ------- ----------                               
DEPT                           TABLE                                            
EMP                            TABLE                                            
BONUS                          TABLE                                            
SALGRADE                       TABLE                                            
STUDENT                        TABLE                                            
EMP10                          TABLE                                            
BIN$B/vbnKyvSiCNnSufkw5+ng==$0 TABLE                                            
TEST4                          TABLE                                            
TEST2                          TABLE                                            
EMP20                          TABLE                                            
EMPINFO                        TABLE                                            

TNAME                          TABTYPE  CLUSTERID                               
------------------------------ ------- ----------                               
TEST3                          TABLE                                            
EMPINFOVIEW                    VIEW                                             
TESTSEQ                        TABLE                                            
HREMP                          SYNONYM                                          

已选择 15 行。

SQL> create synonym abcd for EMPINFOVIEW;

同义词已创建。

SQL> select * from abcd;

     EMPNO ENAME             SAL     ANNLSA DNAME                               
---------- ---------- ---------- ---------- --------------                      
      7782 CLARK            2450      29400 ACCOUNTING                          
      7839 KING             5000      60000 ACCOUNTING                          
      7934 MILLER           1300      15600 ACCOUNTING                          
      7369 SMITH             800       9600 RESEARCH                            
      7566 JONES            2975      35700 RESEARCH                            
      7788 SCOTT            3000      36000 RESEARCH                            
      7876 ADAMS            1100      13200 RESEARCH                            
      7902 FORD             3000      36000 RESEARCH                            
      7499 ALLEN            1600      19200 SALES                               
      7521 WARD             1250      15000 SALES                               
      7654 MARTIN           1250      15000 SALES                               

     EMPNO ENAME             SAL     ANNLSA DNAME                               
---------- ---------- ---------- ---------- --------------                      
      7698 BLAKE            2850      34200 SALES                               
      7844 TURNER           1500      18000 SALES                               
      7900 JAMES             950      11400 SALES                               

已选择 14 行。

五、oracle中的sql优化问题

(一)、 --SQL优化原则。4. 理论上,尽量使用多表查询

(只是说明理论上,因为子查询会对表查询多次,而多表查询是一次性的)

SQL> select e.*
  2  from emp e,dept d
  3  where e.deptno=d.deptno and d.dname='SALES';


SQL> select *
  2  from emp
  3  where deptno = (select deptno
  4                  from dept
  5                  where dname='SALES');

(二)、尽量少使用集合运算

--SQL 原则:5 尽量不要使用集合运算
从这两个sql句子可以看出:

 select deptno,job,sum(sal) from emp group by deptno,job
     union
     select deptno,to_char(null),sum(sal) from emp group by deptno
     union
     select to_number(null),to_char(null),sum(sal) from emp;


 select deptno,job,sum(sal) from emp group by rollup(deptno,job);

-- SQL执行时间的开关

在oracle中打开或者关闭sql语句执行的时间;
set timing on

set timing off

六、oracle中的dcl语句

1、在oracle中执行一条sql语句回显的信息

set feedback on

set feedback off

2、在oracle中执行sql文件

例如:执行d:\temp\testdelete.sql文件如下:

@d:\temp\testdelete.sql

3、使用Scott用户登入oracle的orcl数据库后,在创建视图、索引、同义词的时候都需要系统管理员sys授予Scott用户权限:

如下:

首先要登入sys用户:用户名sys/密码password   as  sysdba链接到sysdba

(用户名和密码的认证方式登入系统管理员的方式)

>sqlplus sys/password as sysdba

直接按回车键;


上面是系统管理员登录的一种方法,当不知道sys系统管理员的用户名和密码的时候,可以使用另外一种登入系统管理的办法:

(主机认证方式,登入系统管理员的账号)

>sqlplus / as sysdba


3.1、登入sys系统管理员的用户后,之后开始授予Scott一些操作权限;

3.1.1、授予Scott创建视图view的权限

SQL> grant create view to scott;

七、oracle中的一些特殊字段

1、select rowid,empno,ename,sal from emp;

rowid是oracle中的一个行地址,也是oracle中的一个伪列,作用是:行地址就相当于数据的指针,指示到数据库的dbf文件;

2、在oracle中,查询给用户下的所有表;

select * from tab;


猜你喜欢

转载自blog.csdn.net/liangwanmian/article/details/79241237
今日推荐