Oracle数据库总结

先来了解几个概念:
数据(Data):
数据库中的存储的基本对象。
数据库(Database):
长期存储在计算机内、有组织、可共享的大量数据的集合。
数据库管理系统(Database Management System,dbms):
是位于用户和操作系统之间的数据管理软件,科学的组织和存储数据、高效的检索和维护数据
数据库系统(Database System,dbs):
数据库系统是为适应数据处理的需要而发展起来的一种较为理想的数据处理系统,
也是一个为实际可运行的存储、维护和应用系统提供数据的软件系统,
是存储介质 、处理对象和管理系统的集合体。

数据库简介

  1. 数据库 DataBase
    数据库是一种软件产品,用于存储数据,管理数据
    的存储仓库,是有效组织在一起的数据集合。
    2.常用的数据库软件
    1)大型数据库

     (1)Oracle  Oracle是甲骨文公司发明的产品
     (2)DB2      DB2是IBM公司推出的产品
     (3)Sybase  是美国Sybase公司推出的数据库

    2)中型数据库

     (1)Sql Server 微软公司推出,一般使用在.net语言开发上
       (2) MySQL属于偏中小型的数据库管理系统。开源免费。08年被Sun公司收购,Sun又被Oracle
           收购。体积小,速度快,成本低。

    3)小型数据库

       Access 微软推出的小型数据库,几乎淘汰。
  2. 结构化查询语言(Structured Query Language,SQL)
    SQL语言用来在数据库上执行数据操作、检索及维护所使用的标准语言,
    是一个综合的、通用的数据库语言。大数据的数据库都使用相同或者相似的语言来操作和维护数据库。
    SQL语言可以查询数据,操纵数据,定义数据,控制数据,软件开发人员、数据库管理人员都可以通过
    SQL语言对数据库执行的特定的操作。

  3. DBA
    数据库管理员(DataBase Administrator,DBA),是从事管理和维护数据库管理系统(DBMS)的

    相关工作人员的统称,属于运维工程师的一个分支,主要负责业务数据库从设计、
    测试到部署交付的全生命周期管理。
  4. Table(表)
    表结构(Table):
    表是数据库存储的基本单元,对应于现实世界中的实体对象,比如部门,职员、学生等,
    表是一个二维结构,由行和列组成,横向为行(Row),也叫记录(Record),用来表示实体的数据,
    比如一个学生的相关信息。纵向为列(Column),也叫作字段(Filed),用来表示实体的属性,
    比如学生的身高、年龄。

                     学号  姓名  性别  年龄  身高  班级
                       1     Li    F     22    173   ..
                       2    Wang   M     23    175
                      ..    ..    ..    ..     ..   ..

    记录(Record):

    每个表包含了若干行数据,它们是表的值,表中的一行称为一条记录,所以可以说,表是记录的有限集合。

    字段(Filed):

    每条记录都由若干个数据项构成,将构成记录的每个数据项称为字段。

    关键字(Key):

    若表中记录的某一字段或字段组合能作为标识记录,则称该字段或字段组合为候选关键字。
    若一个表有多个候选关键字,则选定其中一个为主关键字,也称主键。当一个表仅有唯一

    的一个候选关键字时,该候选关键字就是主关键字,可以用来唯一标识记录行。

  5. SQL语言的分类

    1)数据定义语言DDL(Data Definition Language),是SQL语言集中负责数据结构定义与
    数据库对象定义的语言,包括:

    create语句                 --   数据库对象的创建
    alter语句                    --   修改数据库对象
    drop语句                   --   删除数据库对象
    truncate语句              --   清除表数据

    2)数据操纵语言DML(Data Manipulation Language),用户通过它可以实现对数据表的基本

      操作,包括:增、删、改
      insert            --  插入操作
      update         --  修改操作
      delete          --  删除操作

    3)数据查询语言DQL(Data Query Language),用于主要通过它实现对数据的查询操作

      包括:  select   -- 查询操作

    4)事务控制语言TCL(Transaction Control Language),用来对DML操作进行确认的

      包括:   commit    提交数据
                  rollback    数据回滚
                  savepoint  保存点
           savepoint是事务内部允许部分rollback的标志符。因为事务中对记录做了修改,
           我们可以在事务中创建savepoint来标识不同的点。
           如果遇到错误,就可以rollback到不同的点或直接回来事务最开始的点。     

  1. Oracle数据库的数据类型

    1)数字

        number(n)       数字(最长n位) number(3)           
        number(n,m)   浮点数(总长为n,小数点后为m位)
           例如:number(7,2)   99999.99

    2)字符串

        char(n)       表示定常字符串(方便查询)
                          最长放入n个字符,放入的数据如果不够n个字符则补空格,无论如何都占n个
                          字符的长度
                          char(5)   'abc  '
        varchar(n)  表示变长字符串(节省空间)
                          最长放入n个字符,放入的数据是几个长度就占多大空间
                          varchar(5)   'abc' 
        varchar2(n)  Oracle自己定义的变长字符串

    3)日期

        date      日期
  1. 创建表 == 对象

    1)DDL – create语句

    ​ 语法: create table 表名(字段1 类型 , 字段2 类型,…);
    ​ 注意:表名的命名规则

    1、必须以字母开头;
    2、不使用汉字的列名和表名;(有可能出现乱码)
    3、表名不能超过30个字符;
    4、表名、列名是自由定义的,包含字母(A-Z,a-z)、数字(0-9)、_、$、#组成;
    5、不能使用保留字:如create、select、char等;
    6、对同一个用户不能使用相同的表名称,对同一表不能使用相同的列名;
    7、所有的SQL语句都是以“;”结尾

    练习:创建用户表,

       1)首先咱们先要创建一个.sql文件(可以用咱们的记事本打开)是个脚本文件和咱们的shell程序一样,

    后缀是.sql,这个也可以是别的,但是以sql为后缀容易辨识和识别。
    2)然后输入sql语句。
    3)最后执行咱们的sql文件。

   1.win+R  输入cmd 进入dos窗口

   2.登录sqlplus

       注:
       path>sqlplus 用户名/密码
       path>sqlplus system/tarena
       输入密码后 
       输入行显示提示符:  SQL>

       此时输入: @+文件物理路径
       如:@D:/sql/ch1.sql
       提示Done.之后提交事务 
       commit;     
表中的列名由:
列名                 数据类型
学号id               number(4)
密码password         char(4)
姓名name             char(20)
电话phone            char(20)
邮箱email            varchar2(50)

   drop table user_1;   create table user_1(
         id number(4),
         password char(4),
         name char(10),
         phone char(15),
         email varchar2(20)
      );select * from tab;//查看数据库中的所有表 

2)desc语句(description)
语法: desc 表名; 查看表结构
SQL-> desc user_1;
3)default默认值(默认约束)
作用:可以通过default给列指定默认值

   SQL->   create table user_2(
                       id number(4) default 1001,
                       password char(4) default 'abcd'
                  );
 **4)not null约束**
所用:非空(not null)是一种约束条件,用于确保字段值不能为空;
           默认情况下,任何列都允许有空值;
           当某个字段被设置了非空约束条件,这个字段中必须存在有效值;
           当执行插入数据操作的时候,必须提供这个列的数据;
           当执行更新/修改操作时,不能给这个列的值设置为NULL;
    SQL->
    create table user_3(
         id number(4) default 1001,
         password char(4) not null
    );

–> 1 ‘abcd’ –> 1 ‘abcd’
–> ‘abcd’ –> 1001 ‘abcd’
–> 1 –>报错误

–> 1 ‘abcd’ –> 1 ‘abcd’
–> ‘abcd’ –> 1001 ‘abcd’
–> 1 –>报错误

 **4)not null约束**
所用:非空(not null)是一种约束条件,用于确保字段值不能为空;
           默认情况下,任何列都允许有空值;
           当某个字段被设置了非空约束条件,这个字段中必须存在有效值;
           当执行插入数据操作的时候,必须提供这个列的数据;
           当执行更新/修改操作时,不能给这个列的值设置为NULL;
SQL->
create table user_3(
     id number(4) default 1001,
     password char(4) not null
);

–> 1 ‘abcd’ –> 1 ‘abcd’
–> ‘abcd’ –> 1001 ‘abcd’
–> 1 –>报错误

  1. 修改表

    1)修改表名 – 在建表后如果希望修改表名,可以使用rename语句实现

     语法:  rename 原表名 to 新表名;
      SQL->   rename user_1 to t_user;

    2)增加列

       给表增加列使用 
     语法:alter table 表名 add(字段1 类型 约束, 字段2 类型 约束...);
   SQL->
        alter table user_2 add(
           name char(10) default 'zs',
           phone varchar2(15) not null
       );

3)删除列
使用alter table …drop语句删除不需要的列
语法: alter table 表名 drop(字段1, 字段2, 字段3…);

    SQL->
        alter table user_2 drop(name,phone,password);

4)修改列
建表之后,可以改变表中列的数据类型、长度和默认值;
修改仅对以后插入的数据有效;
如果把长度由大改小,不会成功的;
语法: alter table 表名 modify(字段 类型);

   SQL-> alter table user_2 modify(id number(10));

10.DML语句

 1)insert语句
     给表增加数据
     语法:insert into 表名(字段1, 字段2,...) values(值1, 值2,...);
     注意:执行DML操作后,需要执行commit语句提交,才算真正的确认了此操作
     SQL->
     INSERT INTO T_USER()....
     insert into t_user(id, password, name, phone, email) 
     values(1001, 'abc', 'zs', '138222112', 'a@qq.com');
     commit;
     select  *  from  t_user;      查看t_user表中所有列的数据信息


     --往表中插入某几个字段
     insert into t_user(id, password) values(1002, 'cba');
     commit;
     --往表中所有的字段都插入数据(表后不用写字段,但是values中必须包含所有字段的值)
     insert into t_user values(1003, '1234', 'ww', '138002212', 'b@qq.com');
     commit;


如果插入的列有日期字段,需要考虑日期的格式
默认的日期格式: ‘DD-MM-YY’ 12-3月-19

   //alter session set nls_language = 'SIMPLIFIED CHINESE';
   //alter session set nls_date_language='SIMPLIFIED CHINESE';
   --ANSI格式
   //设置日期格式
   --alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

   alter session set nls_language ='AMERICAN';
   alter session set nls_date_language='AMERICAN';

     可以自定义日期格式,用to_date函数转换为日期类型的数据
     SQL->
     alter table t_user add(bir date);

     --向数据库表中插入当前日期,系统时间--sysdate
     insert into t_user(id, bir) values(1004, sysdate);
     commit;
     --自定义日期格式  to_date()函数   '2019:3:14'
     insert into t_user(id, bir) values(1005, to_date('2019:3:14','YYYY:MM:DD')); 
    commit;
 **2)update语句**
     更新/修改表中的数据
     语法:update 表名 set 字段1=新值1, 字段2=新值2... where 字段=值;
     如果没有where条件,则全表的数据都会被更新,务必小心
   SQL-> 
        update t_user set password='999' where id=1001;
        update t_user set password='666';
        update t_user set password='555',email='p@qq.com' where id=1001;
 **3)delete语句**
    删除表中的数据
    语法: delete from 表名 where 条件;
    如果没有where条件,则表中的数据全部删除
   SQL->  delete from t_user where id=1006;
   SQL->   delete from t_user;   --删除全部的数据
   注意:DDL语句中的truncate,也可以清除表中的所有数据
              语法: truncate table 表名;
    SQL->   truncate table t_user;

    truncatedelete的区别:
   (1delete可以有条件的删除,truncate直接将表的数据全部删除
   (2delete是DML语句,可以回退。truncate是DDL语句,立即生效,无法回退。 
   (3)如果是删除全表的数据,且数据量较大,delete语句效率比truncate语句低。 
  1. SQL Plus 命令

    1)设置行的长度

      一行显示200个字符再换行
     SQL->     set linesize 200;
**2)设置列的宽度**
    **(1)列的属性是数字**
             显示6个数字长度,格式定义为6个9
             SQL->     column  id  format  999999;
      **(2)  列的属性是字符串**
            设置列的宽度为x个字符的长度,格式定义为:a数字
            例如:将列password(字符型)显示最大宽度调整为8个字符
    SQL->    
    column  password  format  a8;
**3)设置分页显示**  
     set pagesize 100;   --每100行数据分页显示
     set pagesize 0;     --设置为0表示不分页
emp表
create table emp(
  empno number(4,0),
  ename varchar2(10),
  job varchar2(9),
  mgr number(4,0),
  hiredate date,
  sal number(7,2),
  comm number(7,2),
  deptno number(2,0)
);
insert into emp values(7369,'SMITH','CLERK',7902,to_date('1980/12/17','YYYY/MM/DD'),800,null,20);
insert into emp values(7499,'ALLEN','SALESMAN',7698,to_date('1981/2/20','YYYY/MM/DD'),1600,300,30);
insert into emp values(7521,'WARD','SALESMAN',7698,to_date('1981/2/22','YYYY/MM/DD'),1250,500,30);
insert into emp values(7566,'JONES','MANAGER',7839,to_date('1981/4/2','YYYY/MM/DD'),2975,null,20);
insert into emp values(7654,'MARTIN','SALESMAN',7698,to_date('1981/9/28','YYYY/MM/DD'),1250,1400,30);
insert into emp values(7698,'BLAKE','MANAGER',7839,to_date('1981/5/1','YYYY/MM/DD'),2850,NULL,30);
insert into emp values(7782,'CLARK','MANAGER',7839,to_date('1981/6/9','YYYY/MM/DD'),2450,NULL,10);
insert into emp values(7788,'SCOTT','ANALYST',7566,to_date('1987/4/19','YYYY/MM/DD'),3000,NULL,20);
insert into emp values(7839,'KING','PRESIDENT',NULL,to_date('1981/11/17','YYYY/MM/DD'),5000,NULL,10);
insert into emp values(7844,'TURNER','SALESMAN',7698,to_date('1981/9/8','YYYY/MM/DD'),1500,0,30);
insert into emp values(7876,'ADAMS','CLERK',7788,to_date('1987/5/23','YYYY/MM/DD'),1100,NULL,20);
insert into emp values(7900,'JAMES','CLERK',7698,to_date('1981/12/3','YYYY/MM/DD'),950,NULL,30);
insert into emp values(7902,'FORD','ANALYST',7566,to_date('1981/12/3','YYYY/MM/DD'),3000,NULL,20);
insert into emp values(7934,'MILLER','CLERK',7782,to_date('1982/1/23','YYYY/MM/DD'),1300,NULL,10);

dept表
create table dept(
  deptno number(2,0),
  dname varchar2(14),
  loc varchar2(13)
);
insert into dept values(10,'ACCOUNTING','NEWYORK');
insert into dept values(20,'RESEARCH','DALLAS');
insert into dept values(30,'SALES','CHICAGO');
insert into dept values(40,'OPERATIONS','BOSTON');

12 .Oracle字符串操作

1)字符串类型

(1)char(n)
​ 表示定常字符串(方便查询)
​ 最长放入n个字符,放入的数据如果不够n个字符则补空格,无论如何都占n个
​ 字符的长度
​ char(5) ‘abc ‘
(2)varchar2
​ 表示字符串数据类型,用来在表中存放字符串信息,如姓名、职业、地址等;
​ char存储定长字符,即存不满补空格,varchar2存放变长字符,存多少占用多少;
​ 例如:char(100) :存放10个字母,补齐90个空格,实际占用100,浪费空间,节省时间
​ varchar2(100):存放10个字母,实际占用10,浪费时间,节省空间
​ char最大取值为2000字节,最多保存2000个英文字符,1000个汉字(GBK),varchar2最
​ 大取值为4000个英文字符,2000个汉字(GBK);
​ char可以不指定长度,默认为1,varchar2必须指定长度;
​ name char; √== name char(1); name varchar2; ×
​ (3) long
​ (4)clob (Character Large Object)字符大对象
​ b->k->m->g 1g=1024m 1m=1024k 1k=1024b
​ long:是varchar2加长版,存储变长字符串,最多达2GB的字符串数据
​ clob:存储定长或变长字符串,最大达4GB的字符串数据
建议:Oracle建议开发中使用clob替代long类型,因为long类型有很多的限制,如** ​ 每个表中只能有1个long类型的列,不能建立索引,不能出现在查询条件中..**

  SQL-> 
         create table student(
              id number(4),
              name long,
              address clob
         );
         drop table student;    --删除表
         create table student(
              id number(4),
              name long,
              address long
         );   --报错误
        create table student(
             id number(4),
             name clob,
             address clob
        );
2)字符串函数

(1)concat 和 || 字符串连接函数
​ 语法: concat(char1,char2)
​ 该函数返回两个字符串连接后的结果,两个参数char1和char2是要连接的两个
​ 字符串。
​ 等价操作:连接操作符 ||

    concat(char1,char2)  == char1 || char2

​ 如果char和char2任何一个为null,相当于连接了一个空格

  SQL->
          select * from emp;   查询的是emp表中所有列的数据
           查询emp表中姓名和工资两列数据
          select ename,sal from emp;    
          select  concat(ename , ':')  from emp;   --> JAMES:
          select  concat(concat(ename,':') , sal)  from emp;   --> JAMES:2500
          等价写法: select ename ||  ':'  || sal  from emp;
          把提成和工资连接
          select comm || sal from emp;
          select sal || comm || empno from emp;

​ (说明:连接的null为空格,空格查询的时候不显示出来)
(2)length函数 –返回字符串的长度
​ 语法: length(char) char表示的是字符串,函数返回字符串的长度
​ 如果(char)字符串的数据类型是varchar2,返回字符串的实际长度;
​ 如果(char)字符串的数据类型是char,返回长度还要包括后补的空格
​ name varchar2(100) – ‘ab’ length(name)–>2
​ name char(100) –’ab….’ length(name)–>100

      SQL->  
           select ename from emp;
           select ename, length(ename) from emp;
           create table mytest(
                name varchar2(10),
                address char(10)
          );
          insert into mytest values('zs','ab');
          select length(name), length(address) from mytest;

(3)upper lower initcap函数
​ 大小写转换的函数,用来转换字符的大小写
​ upper(char) 用于将字符转换为大写形式
​ lower(char) 用于将字符转换为小写形式
​ initcap(char)用于将字符串中每一个单词的首字母大小,其它字母小写
​ (单词之间用空格和非字母字符分隔开的)
​ 如果输入的参数是null值,仍然返回的是null值

 SQL-> insert into emp(empno,ename) values(1001,'helloworld');
          select ename, upper(ename), lower(ename), initcap(ename) from emp;
          insert into emp(empno,ename) values(1002,'ho wo_d'); 

(4)trim ltrim rtrim 函数
​ 1)去掉空格

    trim(char)  去掉字符串两边空格
                 ltrim(char) 去掉字符串左边空格  
                 rtrim(char) 去掉字符串右边空格   
        SQL->  create table t1(id number(4), name char(10));
                 insert into t1 values(1001,'abcd');
                 insert into t1 values(1002,' bb ');
                 select name, trim(name) from t1;
                 select name||id from t1;
                 select name||id, rtrim(name)||id from t1;
2)截去字符串

      trim(c2 from c1)c1的前后截去c2c1c2是字符串
                  ltrim(c1,c2)c1的左边截去c2
                  rtrim(c1,c2)c1的右边截去c2
                 SQL->  insert into t1 values(1003,trim('a' from 'aba'));
                 --b
                        insert into t1 values(1004,ltrim('abc','a'));
                        --bc

(5)lpad rpad函数 ​ 补位函数,语法:

 lpad(char1, n, char2)左补位函数,在字符串char1的左边用char2补足到n位
                rpad(char1, n, char2)右补位函数,在字符串char1的右边用char2补足到n位
                SQL->  select ename, sal from emp;
                       select ename, sal, lpad(sal, 6, '$') from emp;

(6)substr函数 –截取函数
​ 语法: substr(char, m, n) 用于获取字符串的子串,函数返回char中从m位开始
​ 取n个字符
​ 字符串的首位计算从1开始
​ 如果m=0,则从首字符开始,如果m的取值为负数,则从尾部开始
​ 如果没有设置n,或者n的长度超过了char的长度,则取到字符串末尾为止

 SQL-> insert into t1 values(101, substr('abcdefg',3,4));   --cdef
                         insert into t1 values(102, substr('abcdefg',0,4));  --abcd
                         insert into t1 values(103, substr('abcdefg',-2,1));   --f
                         insert into t1 values(104, substr('abcdefg',2,100));  --bcdefg

(7)instr函数
​ 语法: instr(char1, char2, n, m) 返回字串char2在源字符串char1中的位置
​ 从n的位置开始搜索,没有指定n,默认从第1个字符开始搜索
​ m用于指定子串的第m次出现次数,如果不指定默认取值为1

   SQL->    从第1个字符开始搜索,第1次出现的位置
                 insert into t1(id) values(instr('abcabcabc','b'));   id=2
                             从第3个字符开始搜索,第2次出现'b'的位置
                 insert into t1(id) values(instr('abcabcabc','b',3,2));    id=8
  1. Oracle数值操作

    1)数值类型

    (1)number(p) 表示整数

          p表示数字的总位数,取值为1-38

    (2)number(p, s) 表示浮点数

          p表示可以存储的最大数字长度(不包括左右两边的0)   03.1400
          s表示在小数点右边的最大数字长度(包括左侧的0)    3.00014
         注意:指定了s但是没有指定p,则p默认值为38
 ```sql
   SQL->   create table m1(id number(*,2) );
                        desc m1;
 ```



 ######    2)数值函数

  **(1)round函数  四舍五入函数**
           语法:  round(n, m)
                 参数中的n可以是任意数字,指要被处理的数字
                 m必须是整数
                 m取正数则四舍五入到小数点后第m位
                 m取0值则四舍五入到整数位
                 m取负数,则四舍五入到小数点前m位
                 m缺省,默认值为0

 ```sql
 SQL->
    create table mytest(id number(10,4));
    insert into mytest values(45.678);
    insert into mytest values(round(45.678, 2));            --45.68
    insert into mytest values(round(45.678, 0));           --46
    insert into mytest values(round(45.678, -1));          --50
 ```

 **(2)trunc函数    用于截取** 
         语法: trunc(n, m)  n和m的定义和round(n,m)相同,不同的是按照截取的方式
                    处理n


 ```sql
   SQL-> insert into mytest values(trunc(45.678, 2));   --45.67
                      insert into mytest values(trunc(45.678, 0));   --45
                      insert into mytest values(trunc(45.678, -1));   --40
 ```

  **(3)mod函数   取余函数**
        语法:mod(m, n)   返回m除以n后的余数,如果n为0则直接返回m
        SQL->  emp表中工资按1000取余数


 ```sql
  select sal, mod(sal, 1000) from emp;
 ```

  **(4)ceil和floor函数**
         语法:ceil(n)  取大于或等于n的最小整数值
                    floor(n)  取小于或等于n的最大整数值


 ```sql
     SQL-> insert into mytest values(ceil(45.678));   --46
                     insert into mytest values(floor(45.678));   --45
 ```

 **(2)trunc函数    用于截取** 
         语法: trunc(n, m)  n和m的定义和round(n,m)相同,不同的是按照截取的方式
                    处理n


 ```sql
    SQL-> insert into mytest values(trunc(45.678, 2));   --45.67
                      insert into mytest values(trunc(45.678, 0));   --45
                      insert into mytest values(trunc(45.678, -1));   --40
 ```

  **(3)mod函数   取余函数**
        语法:mod(m, n)   返回m除以n后的余数,如果n为0则直接返回m


 ```sql
 SQL->  emp表中工资按1000取余数
        select sal, mod(sal, 1000) from emp;
 ```

  **(4)ceil和floor函数**
         语法:ceil(n)  取大于或等于n的最小整数值
                    floor(n)  取小于或等于n的最大整数值
         SQL-> insert into mytest values(ceil(45.678));   --46
                     insert into mytest values(floor(45.678));   --45

14 Oracle日期操作

1)日期类型

(1)date
​ Oracle中最常用的日期类型,用来保存日期和时间
(2)timestamp
​ 与date的区别是不仅可以保存日期和时间,还能保存小数秒,精确到ns(纳秒)

2)日期关键字

(1)sysdate
​ 是一个Oracle的内部函数,返回当前的系统时间,精确到秒
​ 默认显示格式 DD-MM-YY 16-10月-18
(2)systimestamp
​ 内部函数,返回当前系统时间,精确到毫秒

3)日期转换函数

(1)to_date函数:将字符串按照定制格式转换为日期类型

  语法: to_date(char, fmt)
                            char表示要转换的字符串      fmt表示定制的格式
                            常见的日期格式:
                            YY          2位数字的年份
                            YYYY      4位数字的年份
                            MM        2位数字的月份      10
                            MON      简拼的月份            10月
                            MONTH  全拼的月份           10月
                            DD          2位数字的天          16
                            DY           周几的缩写
                            DAY        周几的全拼
                            HH24     24小时制的小时
                            HH12     12小时制的小时
                            MI           显示分钟
                            SS            显示秒
              SQL->查询'1983-01-01'以后入职的员工
               select ename, hiredate from emp
               where hiredate>to_date('1983-01-01','YYYY-MM-DD');
2)to_char函数:将日期类型的数据转换为字符串类型

             语法:to_char(date,fmt)  将日期类型的数据date按照fmt格式转换为字符串类型
           SQL->将emp表中的入职日期按照  "xxxx年xx月xx日 xx时xx分xx秒" 格式输出
            select ename, hiredate from emp;
            //说明:''表示字符串,在''中再次使用字符串用""
            select ename, to_char(hiredate,'YYYY "年" MM "月" DD "日" HH24 MI  SS') 
            from emp;
 4)日期常用的函数
       (1)last_day函数
               语法:last_day(date):返回日期date所在月的最后一天
               SQL->  select sysdate, last_day(sysdate) from dual;2)add_months函数
               语法:add_months(date, i):返回日期date加上i个月的日期值
                参数i可以任意数字,大部分时候取正值整数
                如果i是小数,将会被截取整数后再参与运算
                如果i是负数,将获得的是减去i个月后的日期值
               SQL-> select sysdate, add_months(sysdate,1) from dual;          
                           select sysdate, add_months(sysdate,1.7) from dual;
                           select sysdate,add_months(sysdate,-1) from dual;3)months_between
               语法:months_between(date1,date2):计算date1和date2两个日期值
                          之间间隔了多少个月
               实际运算是date1-date2,如果date2时间比date1晚,会得到负值
               除非两个日期间隔的是整数月,否则会得到带小数位的结果
               SQL->select months_between('16-10月-18','16-12月-18') from dual;
              12.. 9101112月
               计算200991日到20091010日之间间隔了多少个月
               select months_between('10-10月-09','01-9月-09') from dual;4)next_day函数
                   语法:next_day(date, num) 返回date日期数据的下一个周几,周几
                              是由参数num来决定的
                              num的取值可以直接用数字1-7表示周日-周六
                  SQL-> select sysdate, next_day(sysdate,4) from dual;5)least  greatest函数
                     比较函数
                     语法:least(p1,p2,p3...);         --求最小值
                                greatest(p1,p2,p3...);   --求最大值
                     可以有多个参数,返回结果是参数列表中最大或最小的值
                     多个参数的数据类型必须一致,如果不一致会报错误
                      SQL->  select least(5,1,6) from dual;
                                   select greatest(5,1,6) from dual;6)extract函数
                      语法:extract(date from datetime) 从参数datetime中提取参数date
                                 指定的数据,比如提取年、月、日等
                     SQL->从系统时间systimestamp中提取年月日时分秒
                     select extract(year from systimestamp) from dual;
                     select extract(month from systimestamp) from dual;
                     select extract(day from systimestamp) from dual;
                     select extract(minute from systimestamp) from dual;
                     select extract(second from systimestamp) from dual;
                     select extract(hour from systimestamp)from dual;  (hour+8)

15 Oracle中的虚表

​ dual表,是Oracle中已经设置好的虚表,表中只有一行数据X

    1.oracle中的dual表示一个单行单列的虚拟表。
    2.Dual表是oracle与数据字典一起自动创建的一个表,
        这个表只有1列:DUMMY,数据类型为VERCHAR2(1),
        dual表中只有一个数据'X',Oracle有内部逻辑保证dual表中永远只有一条数据。
    3.Dual表主要用来选择系统变量或求一个表达式的值

    没有表名就没有办法查询,而时间日期并不存放在任何表中,
    于是这个dual虚拟表的概念就被引入,Dual是Oracle中的一个实际存在的表,
    任何用户均可读取,常用在没有目标表的SELECT语句块中

 SQL->  select 1+1 from dual;
              select upper('abc') from dual;
              select sysdate from emp;   报错
              select sysdate from dual;
              select systimestamp from dual;

16 空值操作

1)空值null的含义

​ 有时表中的某些字段值,数据未知或暂时不存在,取值为null
​ 任何数据类型均可取值null

2)空值null的操作

(1)插入null值

   SQL-> create table stu(
                              id number(4),
                              name char(20),
                              gender char(1)
                        );
                       insert into stu(id,name,gender) values(1001,'zs','m');
                       --显式插入null值
                       insert into stu(id,name,gender) values(1002,'ls',null);
                       --隐式插入null值
                       insert into stu(id,name) values(1003,'ww');

(2)更新/修改null值
​ update stu set gender=null;
​ 注意这种更新只有在此列没有非空约束的情况才可以操作
​ 如果某列有非空(not null)约束,则无法更新为null值,上述代码会报错的
(3)null查询条件

 select * from stu where gender is null;  //注意是is,而不是=号
              update stu set gender='m' where gender is null;

​ 总结:给字段设置(更新)为null值用=号,查询条件中判断是否为null值
​ 用is
(4)非空约束
​ 非空(not null)约束用于确保字段值不为空
​ 默认情况,任何列都允许有空值,但在实际的业务逻辑可能会要求某些列
​ 不能取空值;
​ 当某个字段设置了非空约束条件,这个字段中必须存在有效值,即执行插入
​ 操作的时候,必须提供这个列的数据,当执行更新操作时,不能给这个列
​ 设置为null。

  SQL-> create table stu1(
                               id number(4) not null,
                               name char(20) not null,
                               gender char(1) not null
                          ); 
                         insert into stu1(id) values(1001);
3)空值null函数

(1) nvl函数
​ 语法:nvl(p1,p2) 将null转变为非null值
​ 如果p1为null,则取值p2,p2是实际值,如果p1不为null,则还是用p1的值
​ p1和p2可以是任意数据类型,但是两个参数的数据类型必须是一致的
​ SQL->计算员工的月收入(底薪+绩效=月收入)

 select ename,sal,comm,sal+comm from emp;
            select ename,sal,comm,sal+nvl(comm,0) from emp;

(2)nvl2函数
​ 语法:nvl2(p1,p2,p3) 和nvl函数功能类似,都能将null转变为实际值
​ nvl2函数用来判断p1是否为null,如果不是null,返回p2的值,如果
​ 是空,返回p3的值

  SQL->计算员工的月收入
            select ename,sal,comm,nvl2(comm,sal+comm,sal) from emp;
  1. SQL基础查询

    1)基本查询语句

    (1)from子句

```sql
 指定要从哪个表中查询   from emp;
           select * from 表名;
```

**(2)使用别名**
       在SQL语句中可以通过使用列的别名改变标题的显示样式,或者表示计算结果的含义
       语法:是列的别名跟在列名后,中间可以加或不加一个"as"关键字
       别名默认显示为全大写,如果希望别名中区分大小写字符,或者别名中包含空格等
       其它字符,必须用双引号引起来



```sql
  SQL-> select empno,ename,sal*12 from emp;
        select empno as id, ename  "Name" , sal*12 as "Annual Salary" from emp;
```

**(3)where子句**
         where子句的功能限制查询结果
         如果where子句中是和数字比较,*数字可以使用“单引号”引起来,也可以不用*
         如果where子句中是和字符及日期类型的数据比较,则必须用“单引号”引起来


```sql
  SQL->             select ename from emp where deptno=20;
                    select ename from emp where deptno='20';
                    select ename from emp where job=CLERK;   --错误
                       select ename from emp where job='CLERK';
```

**(4)select子句**
         select用于指定要查询的列
         如果要查询所有的列,可以在select后面使用*号
         如果只查询特定的列,可以直接在select后面指定列名,列名之间用逗号隔开

###### 2)查询条件

  **(1)使用  >    <     >=     <=     !=     <>   =**
    SQL->  查询职员中薪水低于2000元的职员信息
                 select ename,sal from emp where sal<2000;
                 查询职员表中不属于部门10的员工信息(  !=  等价于 <> )
                 select ename,sal,deptno from emp where deptno!=10;
                 查询职员表中在1981年1月1日以后入职的职员信息
                  select ename,hiredate from emp
                  where hiredate>'1-1月-81';


​              select ename,hiredate from emp
​              where hiredate>to_date('1981-1-1','YYYY-MM-DD');
 **(2) 使用and  or关键字**
​      在SQL操作中,如果希望返回的结果必须满足多个条件,应该使用and操作符连接条件
​      在SQL操作中,如果希望返回的结果满足多个条件之一即可,应该使用or

```sql
  SQL->查询薪水大于1000并且职位是'CLERK'的职员信息
   select *from emp where sal>1000 and lower(job) = 'clerk';
              查询薪水大于1000或者职位是'CLERK'的职员信息
        select ename,sal,job from emp where sal>1000 or job = 'CLERK';
```

 **(3)使用like条件-- 模糊查询**
      当用户在执行查询时,不能完全确定某些信息的查询条件,或者只知道信息的一部分,
      可以借助于like来实现
      like需要借助于两个通配符:
      %:表示0到多个字符
      _:表示单个字符
      这两个通配符配合使用,构造灵活的匹配条件
     SQL-> select ename, job from emp where ename like '_A%';
**(4)使用  in  和  not in **
     语法:in(list)   用来取出符合列表范围中的数据
                list表示列表值,当列或表达式匹配于列表中的任何一个值时,条件为
                true,该条记录会被显示出来
                in也可以理解为范围比较操作符,只不过这个范围是一个指定的列表值。
                          2000-6000   in(2000,3000,4000,5000,6000)
                not in(list)   取出不符合此列表中的数据记录



```sql
 SQL-> 查询职位是MANAGER或者CLERK的员工
select ename, job from emp
               where job='MANAGER' or job='CLERK';
               //等价写法
               select ename,job from emp
               where job in('MANAGER','CLERK');
               //查询不是部门10或20的员工
              select ename,job,deptno from emp where deptno not in(10,20);
```

 **(3)使用like条件-- 模糊查询**
      当用户在执行查询时,不能完全确定某些信息的查询条件,或者只知道信息的一部分,
      可以借助于like来实现
      like需要借助于两个通配符:
      %:表示0到多个字符
      _:表示单个字符
      这两个通配符配合使用,构造灵活的匹配条件
     SQL-> select ename, job from emp where ename like '_A%';
(4)使用  in  和  not in 
     语法:in(list)   用来取出符合列表范围中的数据
                list表示列表值,当列或表达式匹配于列表中的任何一个值时,条件为
                true,该条记录会被显示出来
                in也可以理解为范围比较操作符,只不过这个范围是一个指定的列表值。
                          2000-6000   in(2000,3000,4000,5000,6000)
                not in(list)   取出不符合此列表中的数据记录


```sql
SQL-> 查询职位是MANAGER或者CLERK的员工
               select ename, job from emp
               where job='MANAGER' or job='CLERK';
               //等价写法
               select ename,job from emp
               where job in('MANAGER','CLERK');
               //查询不是部门10或20的员工
              select ename,job,deptno from emp where deptno not in(10,20);
```

 **(5)between...and...**
        语法:between...and...操作符用来查询某个值范围条件的数据
        最常见的是使用在数字类型的数据范围上,但对字符类型和日期类型数据也同样使用


```sql
SQL->  查询薪水在1500-3000之间的职员信息
        select ename,sal from emp where sal>=1500 and sal<=3000;
        select ename,sal from emp where sal between 1500 and 3000;
```

  **(6)  is null  和  is not null**
       空值null是一个特殊的值,比较的时候不能用"="号,必须使用is null,否则不能得到
       正确的结果。


```sql
SQL-> 查询哪些员工的奖金数据为null
                  select ename,sal,comm from emp where comm is null;
```

   **(7)使用any 和 all条件**
         语法:  any(list)     all(list)
         any和all不能单独使用,需要配合比较操作符(> < >= <=)一起使用
         >any(list) :大于list中最小的值
         <any(list) :小于list中最大的值
         >all(list)   :大于list中最大的值
         <all(list)   :小于list中最小的值


```sql
  SQL-> select empno,ename,job,sal,deptno from emp
                      where sal>any(3500,4000,4500);
```

​     **(8)使用distinct**
​          数据表中有可能存储相同数据的行,当执行查询操作时,默认情况会显示所有行,
​          不管查询结果是否有重复数据
​          当重复数据没有实际意思,经常会需要去掉重复值,需要用distinct来实现
​        

```sql
 SQL->查询员工的部门编号
                   select deptno from emp;
                   查询员工的部门编号,去掉重复值
                   select distinct deptno from emp;
                   查询每个部门的职位
                   select deptno,job from emp;
                   查询每个部门的职位,去掉重复值
                   select distinct deptno,job from emp;
```

​       **(9)查询条件中使用表达式和函数**
​               当查询需要对选出的字段进行进一步计算,可以在数字列上使用算术表达式
​               (+、-、*、/、mod)
​               表达式符合四则运算的默认优先级,如果要改变优先级可以使用括号
​               算术运算主要是针对数字类型的数据,对日期类型的数据可以做加减操作,表示
​               在一个日期值上加或减一个天数
​              

```sql
 SQL->          在查询条件中使用函数(将ename列的值先转换为小写,然后再和'smith'比较)
              select ename from emp where lower(ename)='smith';
              //先将'smith'转换成大写,再和ename列的值比较
              select ename from emp where ename=upper('smith');
             //查询条件中使用表达式
             select ename,sal,sal*12 from emp where sal*12>10000;
```

######    3)排序

​      **(1)使用order by子句**
​               对数据按照一定规则进行排序操作
​              语法:  select column1,column2...
​                           from  表
​                           [where 条件]
​                           [order by column]
​               注意:order by子句必须出现在select语句的最后一个位置
​              

```sql
 SQL->  查询emp表中员工姓名,部门号,并按照部门号排序
                select ename, deptno from emp;
                select ename, deptno from emp  order by deptno;
```

​        **(2)asc 和 desc**
​                asc用来指定升序排序(默认),desc用来指定降序排序
​                null值视为最大,升序排在最后,降序排在最前
​              SQL->查询emp表中的数据,部门号为10,并按照mgr进行排序
​                  select empno,ename,mgr,deptno from emp
​                  where deptno=10
​                  order by mgr;

​              select empno,ename,mgr,deptno from emp
​              where deptno=10
​              order by mgr desc;
​     **(3)多个列排序**
​           当以多列作为排序标准,首先按照第一列进行排序,如果第一列数据相同,再
​       以第二列进行排序,以此类推
​           多列排序时,不管正序还是倒序,每个列都要单独设置排序方式
​     

```sql
   SQL->对员工表的职员排序,先按照部门编码进行正序排列,再按照薪水降序排列
            select ename,deptno,sal
            from emp
            order by deptno asc, sal desc;
```

###### 4)聚合函数

​    **(1)什么是聚合函数**
​            聚合函数也称为分组函数、多行函数、集合函数,参与运算只返回一个结果
​            当查询时需要做一些数据统计,比如:查询职员表中各部门职员的平均薪水,
​            各部门的人数,这些需要统计的数据并不能在职员表中直观的列出,而是要
​            根据现有的数据计算得到结果,这种功能可以使用聚合函数来实现。
   **(2)聚合函数     MAX  MIN**
​            用来取得列或表达式的最大值、最小值
​            用来统计任何数据类型,包括数字、字符串和日期
​           SQL-> 查询员工表的最高薪水和最低薪水  参数是数字
​                       select sal from emp order by sal;
​                       select max(sal), min(sal) from emp;
​                       查询最早和最晚的入职时间,参数是日期
​                      select min(hiredate), max(hiredate) from emp;
​    **(3) 聚合函数  AVG   SUM**
​          用来统计列的平均值、和值
​          只能操作数字类型
​          忽略null值
​       

```sql
   SQL-> 查询员工表中员工的平均薪水和薪水总和
              select avg(sal), sum(sal) from emp;
```

   **(4) 聚合函数   count**
         用来计算表中数据的条数
         忽略null值


```sql
SQL-> 查询员工表中一共有多少条员工数据
                     select count(*) from emp;
                     查询员工表中有多少人是有提成的(忽略没有提成的员工数据)
                     select count(comm) from emp;
```

   **(5)聚合函数对空值的处理**


```sql
 select count(comm),sum(comm),avg(comm)from emp;
       select count(comm),sum(comm),avg(nvl(comm,0))form emp;
```

18 Oracle中的关联查询

1)关联查询的概念

​ 实际应用中所需要的数据,经常会需要查询两个或两个以上的表
​ 这种查询两个或两个以上数据表的查询叫做连接查询
​ 连接查询通常建立在有相互关系的表之间

 dept    emp  
          insert into emp values(1001,'ZS','MANAGER',7839,
          to_date('1983-6-11','YYYY-MM-DD'),3000,200,99);
          commit;
2)关联查询的方式

(1)等值连接
​ 是连接查询中最常见的一种,通常是在有关联关系的表间建立,并将连接条件
​ 设定为有关系的列,使用等号“=”连接相关的表
​ emp–>deptno
​ = 等值连接
​ dept–>deptno
​ 语法: select t1.列, t1.列, … t2.列,t2.列
​ from table1 t1, table2 t2
​ where t1.某列=t2.某列

   SQL->查询职员的姓名、职位以及所在的部门的名字和所在城市
                 select e.ename, e.job, d.dname, d.loc
                 from   emp e, dept d
                 where  e.deptno=d.deptno;

(2)内连接(内连接的结果是和等值连接一样的)
​ 内连接返回所有满足连接条件的记录,等值连接也是。
​ 语法: select t1.列, t1.列, … t2.列…
​ from table1 t1 join table2 t2
​ on t1.某列=t2.某列

 SQL->查询职员的姓名、职位以及所在的部门的名字和所在城市
                         select e.ename, e.job, d.dname, d.loc
                         from emp e join dept d
                         on  e.deptno=d.deptno;

(3)外连接
​ 内连接返回满足条件的记录,外连接是不仅返回满足条件的记录,还将返回不满足
​ 条件的记录,以驱动表为参照。
​ a 左外连接
​ 语法: select t1.列,…t2.列…
​ from table1 t1 left outer join table t2
​ on t1.某列=t2.某列
​ 驱动表: table1 t1

  SQL->查询职员的姓名、职位以及所在的部门的名字和所在城市
                         select e.ename, e.job, d.dname, d.loc
                         from  emp e left outer join dept d
                         on e.deptno=d.deptno;
b 右外连接

​ 语法:select t1.列,…t2.列
​ from table1 t1 right outer join table2 t2
​ on t1.某列=t2.某列
​ 驱动表: table2 t2

 SQL->查询职员的姓名、职位以及所在的部门的名字和所在城市
                          select e.ename, e.job, d.dname, d.loc
                          from emp e right outer join dept d
                          on e.deptno=d.deptno;
c 全外连接

​ 全外连接是指,除了返回满足条件的记录,还会返回不满足连接条件的所有
​ 其它行记录
​ 是左外连接和右外连接结果的总和
​ 语法: select t1.列,…t2.列
​ from table1 t1 full outer join table2 t2
​ on t1.某列=t2.某列

 SQL->查询职员的姓名、职位以及所在的部门的名字和所在城市
                         select e.ename, e.job, d.dname, d.loc
                         from emp e full outer join dept d
                         on e.deptno=d.deptno;

(4)自连接
​ 自连接是一种特殊的连接查询,数据的来源是同一个表,即关联关系来自于
​ 同一个表中的多个列。
​ emp empno
​ mgr
​ 自连接是通过将表用别名虚拟成两个表的方式来实现的查询
​ emp w –> 员工表–>在员工表中可以看到我的部门经理的工号
​ emp m –> 管理表–>在管理表中可以看到的是我的职员的工号

SQL->查询出每个职员的经理名字,以及他们的职位编号
               select  w.empno, w.ename, m.empno, m.ename
               from  emp w join emp m
               on  w.mgr=m.empno;

19 Oracle中的约束

1)约束的作用

​ 约束的全称是约束条件,也称为完整性约束条件
​ 约束是在数据表上强制执行的一些数据校验规则,当执行DML操作时,数据是必须符合
​ 这些规则的,如果不符合则无法执行。
​ 约束条件可以保证表中数据的完整性,保证数据间的商业逻辑

2)约束的种类

(1)非空约束:not null
(2)唯一性约束: unique
​ 唯一性约束条件用于保证字段不出现重复值,当给表的某个列定义了唯一约束条件,
​ 该列的值不允许重复,但是允许是null值。
(3)主键约束: primary key
​ 主键约束条件从功能上看相当于是非空约束且唯一约束的组合。
​ 一个表上只允许建立一个主键,而其它约束条件则没有明确的个数限制
(4)检查约束: check
​ 检查约束条件用来强制在字段上的每个值都要满足check中定义的条件。

  SQL->  create table teacher(
                         id number(4) primary key,
                         name varchar2(50) not null,
                         card number(30) unique,
                         age number(4) check(age>30)
                  );

sql语句的编写顺序:
SQL语句的编写顺序:select —-from—- where—- group by —-having —-order by?

sql语句的执行顺序:
SQL语句的执行顺序:from—–where——group by——having —-select—–order by

执行顺序:

1.from
?????? 先选择一个表,或者说源头,构成一个结果集。
2.where
?????? 然后用where对结果集进行筛选。筛选出需要的信息形成新的结果集。
3.group by
?????? 对新的结果集分组。
4.having
????? 筛选出想要的分组。
5.select
???? 选择列。
6.order by
? ? ?最后完成排序。

创建表 default create table 还有命名规则 不能使用相同的表名和相同列名

查看表结构 DESC+表名 默认值重点,修改表名,增加列,删除列(删除多个字段加逗号),修改列,清除表数据,增删该查 事物控制语言TCL 提交数据,数据回滚,savepoint保存点,update insert delete char 型 各种类型要知道,DESC语句,truncate直接删除表的所有数据和delete的区别,每个表中只能有一个long型

字符串函数一定要记得 length返回字符串长度

补位函数 nvl函数


   Reprint policy


《Oracle数据库总结》 by 胡佳艺 is licensed under a Creative Commons Attribution 4.0 International License