Oracle1

一、为什么要有数据库

数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅仅是存储和管理数据,而转变成用户所需要的各种数据管理的方式。

二、有哪些类型的数据库

层次结构模型:是一种有根结点的定向有序树
网状结构模型:按照网状数据结构建立的数据库系统称为网状数据库系统
关系结构模型:把一些复杂的数据结构归结为简单的二元关系

三、常见的关系型数据库

Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL

四、常见数据库产品的特征

通过平台性、安全性、开放性、可伸缩性(并行性)、性能、客户端支持及应用模式、
操作简便来分析各个数据库的优劣势。
sqlserver
    开放性:只能windows上运行
    安全性:没有获得任何安全证书
    性能:多用户时性能佳
    客户端支持及应用模式:只支持C/S模式, C/S结构只支持windows客户用ADO、DAO、OLEDB、ODBC连接
    使用风险:完全重写的代码,经历了长期的测试,不断延迟,许多功能需要时间来证明。并不十分兼容早期产品。使用需要冒一定风险。
    伸缩性并行性:并行实施和共存模型并不成熟。
    操作性:操作简单,但只有图形界面.
Oracle
    开放性:能在所有主流平台上运行
    安全性:获得最高认证级别的ISO标准认证
    性能:性能高 保持开放平台下 TPC-D和TPC-C世界记录:能在所有主流平台上运行
    安全性:
    性能:
    客户端支持及应用模式:
    客户端支持及应用模式:多层次网络计算支持多种工业标准,用ODBC、JDBC、OCI等网络客户连接.
    使用风险:长时间的开发经验,完全向下兼容。得到广泛的应用。完全没有风险
    伸缩性并行性:很难处理日益增多的用户数和数据卷
    操作性:较复杂, 同时提供GUI和命令行,在windowsNT和unix下操作相同
MySql
    开放性:能在所有主流平台上运行
    安全性:
    性能:
    客户端支持及应用模式:
    使用风险:
    伸缩性并行性:
    操作性:
DB2
    开放性:能在所有主流平台上运行
    安全性:获得最高认证级别的ISO标准认证。
    性能:适用于数据仓库和在线事物处理性能较高
    客户端支持及应用模式:
    使用风险:在巨型企业得到广泛的应用,向下兼容性好。风险小。
    伸缩性并行性:DB2具有很好的并行性。DB2把数据库管理扩充到了并行的、多节点的环境
    操作性:操作简单,同时提供GUI和命令行,在windowsNT和unix下操作相同
Access
    开放性:
    安全性:
    性能:
    客户端支持及应用模式:
    使用风险:
    伸缩性并行性:
    操作性:
Sybase
    开放性:
    安全性:
    性能:
    客户端支持及应用模式:
    使用风险:
    伸缩性并行性:
    操作性:

五、Oracle版本介绍

版本:
    Oracle10g  不支持win7和vista
    Oracle11g  支持市面上所有的操作系统
    Oracle12c

六、Oracle介绍

默认端口是1521

七、Oracle卸载

用Oracle自带的卸载程序不能从根本上卸载Oracle,从而为下次的安装留下隐患,那么怎么才能完全卸载Oracle呢?
那就是直接注册表清除,步骤如下: 
1、 开始->设置->控制面板->管理工具->服务 
    停止所有Oracle服务。 
2、 开始->程序->Oracle - OraHome81->Oracle Installation Products-> 
Universal Installer 
    卸装所有Oracle产品,但Universal Installer本身不能被删除 
5、 运行regedit,选择HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE,按del键删除这个入口。 
6、 运行regedit,选择HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services,滚动 
这个列表,删除所有Oracle入口。
7、 运行refedit,
 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application, 
   删除所有Oracle入口。 
8、 开始->设置->控制面板->系统->高级->环境变量 
    删除环境变量CLASSPATH和PATH中有关Oracle的设定 
9、 从桌面上、STARTUP(启动)组、程序菜单中,删除所有有关Oracle的组和图标 
10、 删除\Program Files\Oracle目录 
11、 重新启动计算机,重起后才能完全删除Oracle所在目录 
12、 删除与Oracle有关的文件,选择Oracle所在的缺省目录C:\Oracle,删除这个入 
     口目录及所有子目录,并从Windows目录(一般为C:\WINDOWS)下删除oralce文件等等。 
13、 WIN.INI文件中若有[ORACLE]的标记段,删除该段 
14、 如有必要,删除所有Oracle相关的ODBC的DSN 
15、 到事件查看器中,删除Oracle相关的日志 
说明: 
如果有个别DLL文件无法删除的情况,则不用理会,重新启动,开始新的安装, 
安装时,选择一个新的目录,则,安装完毕并重新启动后,老的目录及文件就可以删除掉了

八、Oracle11g安装

Oracle安装时要解锁SCOTT和HR这两个用户,因为这两个用户默认是锁住的。
解锁后,要修改一下密码,一般
scott/triger
hr/hr















九、Oracle组成

1)Oracle数据库的组成
    分为:一个 Oracle 实例 和一个 Oracle 数据库组成
        Oracle 数据库: 位于硬盘上实际存放数据的文件, 这些文件组织在一起, 成为一个逻辑整体, 即为 Oracle 数据库. 因此在 Oracle 看来, “数据库” 是指硬盘上文件的逻辑集合, 必须要与内存里实例合作, 才能对外提供数据管理服务。
        Oracle 实例: 位于物理内存里的数据结构. 它由一个共享的内存池和多个后台进程所组成, 共享的内存池可以被所有进程访问. 用户如果要存取数据库(也就是硬盘上的文件) 里的数据, 必须通过实例才能实现, 不能直接读取硬盘上的文件。
2)Oracle数据库结构
    SGA(System Global Area):由所有服务进程和后台进程共享;
    PGA(Program Global Area):由每个服务进程、后台进程专有;每个进程都有一个PGA。
3)表空间和数据文件
    表空间为逻辑概念,数据文件为物理概念
    表空间由多个数据文件组成
        数据文件只能属于一个表空间
4)段、区和块
    段存在于表空间中
    段是区的集合
    区是数据块的集合
    数据块会被映射到磁盘块
5)数据库的逻辑和物理结构





十、Oracle数据库产品服务器端的安装与数据库实例配置

1)Oracle服务器的下载
https://www.oracle.com/index.html
2)Oracle服务器的安装需求
系统需求
    内存需求:
        –   1 GB
    磁盘空间需求:
        swap 区需要1.5BG
        /tmp 目录需要400 MB 的磁盘空间
        Oracle软件需要 1.5 GB 到 3.5 GB
        准备1.2 GB 用来重装数据库 (可选)
        为快速恢复区准备2.4 GB   (可选)
3)Oracle服务器的安装步骤详解
    Oracle安装步骤win2008
4)Oracle服务介绍
    Oracle * VSS Writer Service - Oracle卷映射拷贝写入服务
    OracleDBConsole* - Oracle数据库控制台服务
    OracleJobScheduler*  - Oracle作业调度服务
    OracleMTSRecoveryService - 服务端控制
    OracleOraDb11g_home1ClrAgent - Oracle数据库.NET扩展服务的一部分
    OracleOraDb11g_home1TNSListener - 监听器服务
    OracleService*  - 数据库服务,是Oracle核心服务该服务

十、SQL*PLUS的使用方法与常见命令

0)登录
    sqlplus scott/tiger  
    这样就可以登录了。
1)显示设置
set linesize 120;
set pasesize 20;
set feedback off/on;
set serveroutput on/off;
col 列名 for 9999;修改显示数值列的长度
col 列名 for a10; 修改字符列的长度
2)常用命令
查看系统变量 show all;
查看当前用户 show user;
查看错误 show error;
多行注释 /**/
单行注释 --
文件输出 新写入(spool 文件地址)继续写入(spool 文件地址 append)
关闭(spool off;)    
执行缓冲区命令 /
打开缓冲区文件 ed
清屏 - 2种方式 clear screen;  host cls;
退出 - exit
查询参数 select * from v$nls_parameters;

十一、Oracle建表空间

1)表空间介绍
    表空间是数据库中最大的逻辑单位,Oracle数据库采用表空间将相关的逻辑组件
组合在一起,一个Oracle数据库至少包含一个表空间。每个表空间由一个或多个
数据文件组成,一个数据文件只能与一个表空间相联系。
2)表空间类型
    永久性表空间:一般保存表、视图、过程和索引等的数据
    临时性表空间:只用于保存系统中短期活动的数据
    撤销表空间:用来帮助回退未提交的事务数据
3)创建表空间
    Create tablespace 表空间名
    Datafile ‘文件路径’ size 大小
    Autoextend on/off next 大小 maxsize 大小;
4)查询表空间
    //查看所有的表空间
    select * from dba_tablespaces;
    //查看所有的表空间的文件
    select * from dba_data_files;
5)修改表空间
    //增加表空间文件
    Alter tablespace 表空间名 add datafile ’文件路径’ size 大小
    Autoextend on ;
    //修改表空间文件的大小
    Alter database datafile=’文件路径’ resize 大小;
    //修改表空间的扩展大小和最大值
    Alter database datafile=’文件路径’ autoextend on next 大小 maxsize 大小;
6)删除表空间
    drop tablespace 表空间名;
    Drop tablespace 表空间名 including contents and datafiles;

十二、PL/SQL developer工具的常用功能


十三、plsqldev工具的常用功能


十四、数据库用户角色与权限

1)三者的介绍
2)三者之间的关系

十五、权限

1)什么是权限
    所有的操作都需要系统的认可,这种认可就是权限。
2)都有哪些权限
     select * from system_privilege_map;
3)限对应
//1.所有用户所对应的权限
select * from dba_sys_privs;
//2.当前用户的权限
select * from user_sys_privs;
//3.所有角色对应的权限
    select * from role_tab_privs; 

十六、数据库用户

1)系统常见用户
    sys 超级用户,主要用来维护系统信息和管理实例,以SYSDBA或SYSOPER角色登录。
    system  默认的系统管理员,拥有DBA权限,通常用来管理Oracle数据库的用户、权限和存储,以Normal方式登录。
    scott   示范用户,使用users表空间。一般该用户默认密码为tiger
    
2)查询系统用户
    //查询数据库里面所有的用户
    select * from dba_users;
    //查看当前用户能管理的所有用户
    select * from all_users;
    //查看当前账户
    select * from user_users;

3)解锁用户
    alter user hr account lock/unlock;

4)创建用户
    Create user 用户名 identified by 密码 default tablespace 表空间名;

5)修改用户密码
    Alter user hr identified by 新密码;

6)删除用户
    Drop user 用户名 cascade;

十七、角色

正是因为需要把每个权限都要赋给不同的用户,操作起来没有那么简便,所以就有了角色。

1)系统默认角色
Oracle提供了三种标准的角色(role):connect、resource和dba。
    1. connect role(连接角色)
    临时用户,特别是那些不需要建表的用户,通常只赋予他们connect role。     connect是使用Oracle的简单权限,这种权限只有在对其他用户的表有访问时,包括select、insert、update和delete等,才会变得有意义。
    2. resource role(资源角色)
    更可靠和正式的数据库用户可以授予RESOURCE role。resource提供给用户另外的权限以创建他们自己的表、序列、过程、触发器、索引和簇。
    3. dba role(数据库管理员角色)
    dba role拥有所有的系统权限--包括无限制的空间限额和给其他用户授予各种权限的能力。
除此以上角色外;还可以自行创建角色。用户创建的role可以由表或系统权限或两者的组合构成。为了创建role,用户必须具有CREATE ROLE系统权限。

2)创建角色的权限
    grant create role to 用户名;
3)创建角色
    Create role 角色名;
3)删除角色
    Drop role 角色名;
4)查询角色
    //查询所有角色
    select * from dba_roles;
    //查询当前用户所拥有的角色
    select * from user_role_privs;
5)把角色赋给用户
    Grant 角色名 to 用户名

十八、DCL数据控制语言

1)授予语法
    Grant 角色 [on 表名] to 用户;
    Grant 操作 on 表名 to 用户;
2)授予
    //授予用户连接权限 -- 用户在创建的时候有默认表空间。
    Grant connect,resouce to chinasoft;
    //授予用户的表的操作
    Grant select,update on emp to chinasoft;

    //授予某个角色权限
    Grant connect,resource to 角色名;
    //把角色赋给用户
    Grant 角色名 to 用户名;


3)撤销
    //撤销权限
    Revoke connect,resource from 用户;
    Revoke select,update from 用户;
    //撤销角色
    Revoke 角色名 from 用户名;

十九、SQL数据类型

VARCHAR2(size)
    可变长度的字符串,其最大长度为size个字节;size的最大值是4000,而最小值是1;你必须指定一个VARCHAR2的size;

NVARCHAR2(size)
    可变长度的字符串,依据所选的国家字符集,其最大长度为size个字符或字节;size的最大值取决于储存每个字符所需的字节数,其上限为4000;你必须指定一个NVARCHAR2的size;

NUMBER(p,s)
    精度为p并且数值范围为s的数值;精度p的范围从1到38;数值范围s的范围是从-84到127;例如:NUMBER(5,2) 表示整数部分最大3位,小数部分为2位;NUMBER(5,-2) 表示数的整数部分最大为7其中对整数的倒数2位为0,前面的取整。NUMBER 表示使用默认值,即等同于NUMBER(5);
    
LONG
    可变长度的字符数据,其长度可达2G个字节;
DATE
    有效日期范围从公元前4712年1月1日到公元后9999年12月31日

RAW(size)
    长度为size字节的原始二进制数据,size的最大值为2000字节;你必须为RAW指定一个size;
    
LONG RAW
    可变长度的原始二进制数据,其最长可达2G字节;

CHAR(size)
    固定长度的字符数据,其长度为size个字节;size的最大值是2000字节,而最小值和默认值是1;
    
NCHAR(size)
    也是固定长度。根据Unicode标准定义
CLOB
    一个字符大型对象,可容纳单字节的字符;不支持宽度不等的字符集;最大为4G字节
NCLOB
    一个字符大型对象,可容纳单字节的字符;不支持宽度不等的字符集;最大为4G字节;储存国家字符集
BLOB
    一个二进制大型对象;最大4G字节

BFILE
    包含一个大型二进制文件的定位器,其储存在数据库的外面;使得可以以字符流I/O访问存在数据库服务器上的外部LOB;最大大小为4G字节.
    

二十、DDL语言(表操作)

1)什么是表
    用一个excle表来保存一个Student对象。
    注意:用Excel演示出来
2)创建表
    Create table 表名(
    字段 字段类型 约束条件,
    字段 字段类型 约束条件,
    ....
    字段 字段类型 约束条件,
    [约束条件]
    );
3)字段约束
    Primary key
    Unique
    Not null
    Check check(usex in (0,1))/check(uage between 1 and 100)/check(unum > 0)
4)添加约束
    alter table users modify uage constraint users_age not null;
5)删除约束
    alter table users drop constraint users_unum;
    alter table users modify uage null;
6)查看表
    1.查看当前用户的所有表
    select * from tabs;
    select * from user_tables;
    2.查看所有用户的所有表
    select * from dba_tables;
    3.查看当前用户的所有表(和当前用户所管理的用户)
    select * from all_tables;
    4.查看当前用户所有的表
    select * from tab;
    5.查看表结构
    desc emp;

7)修改表
    1.添加字段
        alter table test01 add(
                sex number(5) not null
            );
    2.修改属性
        alter table test01 modify(sex number(20),name varchar2(50));
    3.删除字段
        alter table test01 drop(sex,age); 
    4.修改字段名称
        alter table test01 rename column name to tname;
    5.修改表名称
        alter table test01 rename to test00;
        rename test00 to test01;

8)删除表
    drop table test01;  // 删除后可以在回收站查看并恢复
    drop table user01 purge;// 删除后不可以在回收站查看和恢复

二十一、回收站操作

1)回收站是什么

2)查看回收站
    show recycle;
    select * from recyclebin;
3)从回收站恢复表
    flashback table user01 to before drop;
4)清空回收站
    purge recyclebin;

二十二、伪表

1)伪表
    管理员提供的表,查询的数据跟表没有关系,但是还需要满足语法,这个时候就需要用这个伪表。
    select 'zhangsan' from dual;
2)伪列rowid
    select rowid,ename from emp;
3)伪列rownum
    select rownum,ename from emp;

二十三、常用函数

1)数字型
    round 四舍五入
        select round(10.5) from dual;//10.6、10.3   
        select round(10.336,2) from dual; //10.336、10.334
    trunc 精度
    select trunc(20.55) from dual;//20.55、20   
    select trunc(20.55,2) from dual;//0,1,2,3
2)字符串
    lower 转小写
        select lower('ZhongRuan') from dual;
    upper 转大写
        select upper('zhongruan') from dual;
    initcap 首字母大写
        select initcap('zhongruan') from dual;
    substr 字符串截取
        select substr('zhongruan',1) from dual;   
        select substr('zhongruan',1,2) from dual;
    length 字符长度
        select length('zhongruan') from dual;  
        select length('中软') from dual;
    lengthb 字节长度
        select lengthb('中软') from dual;
    instr 查找子串
        select instr('zhongruan','ruan') from dual;
    lpad 左填充
        select lpad('zhang',10) from dual;  
        select lpad('zhang',10,'*') from dual;
    rpad 右填充
        select rpad('zhong',10) from dual;  
        select rpad('zhong',10,'*') from dual;
    trim 去掉字符
        select trim('z' from 'zhong') from dual;
    replace 替换
        select replace('zhong','o','a') from dual;
    concat 拼接 ||
        select concat('hello',' world') from dual;  
        select 'zhong' || 'ruan' from dual;

3)转换函数
    to_char 转成char类型
        select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual; 
        select to_char(sal,'L9,999.99') from emp;
    to_number 转成number类型
        select to_number('2017') from dual;
    to_date 转成日期
        select to_date('2017-08-09','yyyy-mm-dd') from dual;
    
4)时间
    date格式 当前时间
        select sysdate from dual;
        select sysdate-1 from dual;
        select sysdate+1 from dual;
    修改日期格式
        alter session set NLS_DATE_FORMAT='yyyy-mm-dd';   
        select sysdate from dual;
        alter session set NLS_DATE_FORMAT='DD-MON-RR';  
        select sysdate from dual;
    timestamp格式 当前时间
        select systimestamp from dual;
    两种时间格式的区别
        date显示的是年月日时分秒   
        timestamp显示的年月日时分秒还包括了小数秒 
    两种时间格式的转换
        timestamp转date:select cast(systimestamp as date) from dual;
        date转timestamp:select cast(sysdate as timestamp) from dual;
    add_months 增加月
        add_months select add_months(sysdate,1) from dual;
    months_between 时间相距几月
        select months_between(sysdate,to_date('2017-08-09','yyyy-mm-dd')) from dual;
    extract 获取年月日时分秒
        select extract(year from sysdate) from dual;  
        select extract(month from sysdate) from dual;  
        select extract(day from sysdate) from dual;   
        select extract(hour from timestamp '2017-03-09 14:05:30') from dual;
    last_day 月末时间
        select last_day(sysdate) from dual;  
    next_day 一周时间 
        select next_day(sysdate,'星期日') from dual;

5)聚合函数
    sum 求和
        select sum(sal) from emp;
    avg 求平均值
        select avg(sal) from emp;
    count 计数
        select count(empno) from emp;
    max 求最大值
        select max(sal) from emp;
    min 求最小值
        select min(sal) from emp;

6)其它函数
    nvl
        提出问题:select ename,sal,comm from emp;  
        解决问题:select ename,sal,nvl(comm,0)comm from emp;
    nvl2(a,b,c)
        当a=null时,返回c; 否则返回b(3元运算符) 
        select ename,sal,nvl2(comm,'有值','没值')comm from emp;

二十四、DML语言

1)新增数据
    insert into student (id,sname,sage) values(1,'zhangsan',18);
    insert into student values(1,'zhangsan',18);
2)修改数据
    update 表名 set column1=newValue,column2=newValue,...where 条件;
    update users03 set u_age=20,u_sex=2 where u_id=100;
3)删除数据
    delete from emp where empno = 8888;//根据条件删除表数据
    truncate table emp01; //清空表数据
4)查询语句 - 基本查询
    基本查询
        select * from emp;
    列名查询
        select empno from emp;
        select empno,ename from emp;
    查询时列名加减乘除操作
        select ename,sal+100 from emp;
        select ename,sal-100 from emp;
        select ename,sal*100 from emp;
        select ename,sal/100 from emp;
        select sal*deptno from emp;
    别名
        select ename name,sal*10 sal from emp;
        select empno as "员工号",ename "姓名" ,sal 月薪 from emp;
        
        注意: 有as 和没有as 与有双引号和没有双引号的区别?
            如果是别名中有空格,就必须要有双引号。否则就是错误的sql。
            
            别名使用双引号,以便在别名中包含空格或者特殊字符并区分大小写。
    去重 distinct
        select distinct job from emp;
        distinct作用于多列
        select distinct deptno,job from emp;
            这个是只要deptno,job合起来不相同则不相同。
        

二十五、DML语言-单表复杂查询

1)过滤查询 等于
    select * from emp where empno = 7169;
    select * from emp where ename = ‘SMITH’;
    select * from emp where hiredate = '17-12月-1980';

2)过滤查询 大于小于
    select * from emp where sal > 2000;
    select * from emp where sal < 2000;

3)过滤查询 在两个值之间 [a,b]
    select * from emp where sal between 800 and 1600;
    注意:小值在前,大值在后面
4)过滤查询 在一个集合中 in
    select * from emp where deptno in (20,30);
    
5)过滤查询 不在一个集合中 not in
    select * from emp where deptno not in(20,30);
    ()括号里面不能出现null

6)过滤查询 根据两个条件查询 and
    select * from emp where sal = 3000 and ename = 'SCOTT';

7)过滤查询 根据两个条件查询 or
    select * from emp where sal = 3000 or sal = 1600;

8)过滤查询 只要一条数据
    select * from emp where rownum = 1;

9)模糊查询
    select * from emp where ename like '%S%';
    select * from emp where ename like '%S____';
    select * from emp where ename like '_A__';
    % :模糊匹配,任意多个字符
    _ : 模糊匹配,但是只能匹配一个字符

10)模糊查询 - 转义字符
    insert into emp(empno,ename,sal) values(8888,'Zhang_S',3000.00);
    select * from emp where ename like '%\_%' escape '\';
    用a-z都可以。

11)排序 asc(默认)|desc
    select * from emp order by sal;
    select * from emp order by sal desc;

    select * from emp order by deptno,sal;
    select * from emp order by deptno,sal desc;
    //按照两个列排序

12)排序 order by后面+ 列名 表达式 别名 序号
    select * from emp order by sal;
    select * from emp order by sal*12;
    select empno num,ename name,sal s from emp order by s;
    select empno,ename,sal from emp order by 3;
13)分组 group by 
    //求每个部门的平均工资
    select deptno,avg(sal) from emp group by deptno;
    //按照job和deptno分组
    select job,deptno from emp group by job,deptno;
    //求部门平均工资大于2000的部门
    select deptno from emp group by deptno having avg(sal) > 2000;
    //求10号部门的平均工资
    select deptno,avg(sal) from emp group by deptno having deptno = 10;


注意:
    在分组查询中只能出现分组列和聚合函数。
    在分组查询中,条件列必须出现在group by后。
    在分组查询中,group by后可以有多列,但是必须要出现在查询条件中。

二十六、DML语言-多表复杂查询

1)笛卡尔集
    没有WHERE子句的交叉联接将产生联接所涉及的表的笛卡尔集。
    select * from emp,dept;
2)查询员工信息:员工号 姓名 月薪 部门名称
    select e.empno,e.ename,e.sal,d.dname from emp e,dept d where e.deptno = d.deptno;
3)按部门统计员工人数: 部门号  部门名称 人数
    select d.deptno,d.dname,count(e.empno) from emp e,dept d where e.deptno = d.deptno group by d.deptno,d.dname;
先查
    select d.deptno,d.dname from emp e,dept d where e.deptno = d.deptno;
再统计
4)外连接
    外连接:对于不成立的记录,任然希望包含在最后的结果中
    左外连接: where e.deptno=d.deptno 不成立时,等号左边所代表的表任然被包含
    where e.deptno=d.deptno(+)
    等号左边的是左表,等号右边的是右表
    右外连接: where e.deptno=d.deptno 不成立时,等号右边所代表的表任然被包含
    where e.deptno(+)=d.deptno
    等号左边的是左表,等号右边的是右表
5)左外:按部门统计员工人数: 部门号  部门名称 人数(包含部门没有人的部门)
    Dept表中有多余的部门,emp表中的员工都是有部门的。所以dept表是左表
    select d.deptno,d.dname,count(e.empno) from emp e,dept d where  d.deptno = e.deptno(+) group by d.deptno,d.dname;

    Left join写法--leftjoin 左边的是左表  右边的是右表
    select d.deptno,d.dname,count(e.empno) from dept d left join emp e on d.deptno = e.deptno group by d.deptno,d.dname;


6)右外:按部门统计员工人数: 部门号  部门名称 人数(包含部门没有人的部门)
    select d.deptno,d.dname,count(e.empno) from emp e,dept d where e.deptno(+) = d.deptno group by d.deptno,d.dname;

Right join写法--rightjoin 左边是右表  右边是左表
    select d.deptno,d.dname,count(e.empno) from emp e right join dept d on e.deptno = d.deptno group by d.deptno,d.dname;

7)内连接 inner join
    只返回两个表中联结字段相等的行
    查询员工信息:员工号 姓名 月薪 部门名称
    select e.empno,e.ename,e.sal,d.dname from emp e,dept d where d.deptno = e.deptno;

    select e.empno,e.ename,e.sal,d.dname from emp e inner join dept d on d.deptno = e.deptno;

8)自连接
    查询的多个表都是自己一张表
    查询员工信息: ***的老板是***
    select e.ename||'的老板是'||b.ename from emp e,emp b  where e.mgr=b.empno;

二十七、DML语言-子查询

1)步骤
    条件是一条查询语句,返回值是主查询的范围。
    先把子查询语句写出来,然后再写主查询

2)查询工资比SCOTT高的员工信息
    select sal from emp where ename = 'SCOTT';
    select * from emp where sal > 3000;
    select * from emp where sal > (select sal from emp where ename = 'SCOTT');

3)查询员工的姓名 和薪水
    select ename,sal from emp;
    select * from (select ename,sal from emp);

4)查询部门名称为SALES的员工信息
    select deptno from dept where dname = 'SALES';
    select * from emp where deptno = (select deptno from dept where dname = 'SALES');

5)查询部门名称为SALES和ACCOUNTING的员工信息
    select deptno from dept where dname='SALES' or dname='ACCOUNTING';
    select * from emp where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');

    select e.* from emp e,dept d where e.deptno=d.deptno and (d.dname='SALES' or d.dname='ACCOUNTING');

6)查询工资比30号部门任意一个员工高的员工信息
    select sal from emp where deptno=30;
    select * from emp where sal > any (select sal from emp where deptno=30);

7)查询工资比30号部门所有员工都高的员工信息
    select * from emp where sal >all (select sal from emp where deptno=30);

8)集合合并 union 和 union all 
    union : 多个结果合并在一起显示出来,没有重复
    union all : 将所有的结果全部显示出来,不管是不是重复

    select * from emp where deptno = 10
    union
    select * from emp where ename = 'CLARK'


    select * from emp where deptno = 10
    union all
    select * from emp where ename = 'CLARK'

9)交集 intersect
    对两个结果集进行交集操作,不包括重复行

    select * from emp where deptno = 10
    intersect
    select * from emp where deptno = 20

    select * from emp where deptno = 10
    intersect
    select * from emp where ename = 'CLARK'

10)minus
    对两个结果集进行差操作,不包括重复行
    minus 前边是大集合,后边是小集合。写反的结果不同

    //有结果
    select * from emp where deptno = 10
    minus
    select * from emp where ename = 'CLARK'

    //没有结果
    select * from emp where ename = 'CLARK'
    minus
    select * from emp where deptno = 10

11)exists 和 not exists

    exists表示()内子查询语句返回结果不为空说明where条件成立就会执行主sql语句,如果为空就表示where条件不成立,sql语句就不会执行。

    带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。 
    使用存在量词EXISTS后,若内层查询结果非空,则外层的WHERE子句返回真值否则返回假值。 
    由EXISTS引出的子查询,其目标列表达式通常都用*,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义。 

如果部门名称以字母A开头,则查询所有员工信息(使用exists)
    select * from dept where dname like 'A%';
    select * from emp where deptno = 10;
    select * from emp where exists (select * from dept where dname like 'A%' and emp.deptno = deptno)
    先看部门名称是否是A开头,然后 emp表的deptno 和 dept表的deptno必须相同者两个条件去查询emp表

    not exists和exists相反,子查询语句结果为空,则表示where条件成立,执行sql语句。负责不执行

    查询10号部门以外的员工
        select a.deptno,a.ename from scott.emp a where not exists(select * from scott.dept b where b.deptno=a.deptno and b.deptno=10) ;

二十八、TCL事务控制语言

1)什么是事务
    事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。
    一个事务中的一系列的操作要么全部成功,要么一个都不做。 
    事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作。
2)事务的特性
    原子性(Atomicity)
        事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做

    一致性(Consistency)
        事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。 

    隔离性(Isolation)
        一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

    持久性(Durability)
        也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。 


案例:
    小明去银行给小红转钱。小明卡上有1000,小红卡上有500,小明给小红转500块
    步骤:1.从小明卡里扣除500  2.在小红的卡里加500    
        最后的结果小明卡里有500,小红卡里有1000.如果从小明的卡里扣了500,然后程序报错了,结果应该怎样?

3)脏读
    脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。

脏读:一个事务读取到了另外一个事务没有提交的数据
    事务1:更新一条数据
        -->事务2:读取事务1更新的记录
    事务1:调用commit进行提交
    
    此时事务2读取到的数据是保存在数据库内存中的数据,称为脏读。
    读到的数据为脏数据
    详细解释:
        脏读就是指:当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

4)不可重复读
    在同一事务中,两次读取同一数据,得到内容不同
    事务1:查询一条记录
        --->事务2:更新事务1查询的记录
       --->事务2:调用commit进行提交
    事务1:再次查询上次的记录
        此时事务1对同一数据查询了两次,可得到的内容不同,称为不可重复读

5)幻读
    同一事务中,用同样的操作读取两次,得到的记录数不相同
    事务1:查询表中所有记录
         -->事务2:插入一条记录
         -->事务2:调用commit进行提交
    事务1:再次查询表中所有记录

    此时事务1两次查询到的记录是不一样的,称为幻读
    详细解释:
        幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

6)事务的隔离级别
    TRANSACTION_NONE  不使用事务。
    TRANSACTION_READ_UNCOMMITTED  允许脏读。
    TRANSACTION_READ_COMMITTED  防止脏读,最常用的隔离级别,并且是大多数数据库的默认隔离级别
    TRANSACTION_REPEATABLE_READ  可以防止脏读和不可重复读,
    TRANSACTION_SERIALIZABLE  可以防止脏读,不可重复读取和幻读,(事务串行化)会降低数据库的效率

7)事务操作-保存点
    savepoint 保存点名称
8)事务操作-提交
    commit;
9)事务操作-回滚
    rollback to 保存点;

二十九、TCL事务控制语言

1)运算符介绍

2)算术运算符
    +、-、*、/
    
    乘除的优先级高于加减。
    优先级相同时,按照从左至右运算
    可以使用括号改变优先级。

3)比较(关系)运算符
    =、!=、<>、< 、 > 、 <= 、 >= 、 between...and... 、in 、like 、is null

4)逻辑运算符
    AND(逻辑与),表示两个条件必须同时满足
    OR(逻辑或),表示两个条件中有一个条件满足即可
    NOT(逻辑非),返回与某条件相反的结果

5)连接运算符
    ||
    把列与列,列与字符连接在一起。可以用来'合成'列。
    select ename || '的职位是' || job from emp;

6)集合运算符
    union(并集无重复)
    union all(并集有重复)
    intersect(交集,共有部分)
    minus(减集,第一个查询具有,第二个查询不具有的数据)
7)运算符优先级
    1   算术运算符
    2   连接符
    3   比较符
    4   IS[NOT]NULL, LIKE, [NOT]IN
    5   [NOT] BETWEEN
    6   NOT
    7   AND
    8   OR
    可以使用括号改变优先级顺序;OR的优先级最低,算术运算符的优先级最高。

三十、视图

1)什么是视图
    视图是由一个或者多个表组成的虚拟表;那些用于产生视图的表叫做该视图的基表。视图不占用物理空间,这个也是相对概念,因为视图本身的定义语句还是要存储在数据字典里的。视图只有逻辑定义。每次使用的时候只是重新执行SQL。一个视图也可以从另一个视图中产生。视图没有存储真正的数据,真正的数据还是存储在基表中。一般出于对基本的安全性和常用的查询语句会建立视图;并一般情况下不对视图进行新增、更新操作。

2)视图的作用
    1、视图能够简化用户的操作
    2、视图使用户能以多钟角度看待同一数据
    3、视图对重构数据库提供了一定程度的逻辑独立性
    4、视图能够对机密数据提供安全保护
    5、适当的利用视图可以更清晰的表达查询
3)视图的语法
    create or replace view 视图名称
    as
    Select 语句;
4)创建视图的权限
    grant create view to 用户;
5)视图操作
    查询数据
        select * from 视图名;
    添加数据
        insert into 视图名(字段,字段) values(值,值);
    修改数据
        update 视图名 set 字段=值 where 条件;
    删除数据
        delete from 视图名 where 条件;
    基于多个表建立视图
        create or replace view v_emp_dept 
        as
        select e.empno,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.deptno,d.dname,d.loc from emp e,dept d where e.deptno = d.deptno;

6)删除视图
    drop view 视图名;

三十一、同义词

1)同义词介绍
    同义词是数据库模式对象的一个别名,经常用于简化对象访问和提高对象访问的安全性。在使用同义词时,Oracle数据库将它翻译成对应模式对象的名字。与视图类似,同义词并不占用实际存储空间,只有在数据字典中保存了同义词的定义。在Oracle数据库中的大部分数据库对象,如表、视图、同义词、序列、存储过程等,数据库管理员都可以根据实际情况为他们定义同义词。隐藏对象名称和所有者。

2)同义词分类
    私有同义词
        私有同义词由创建它的用户所有
    共有同义词
        公有同义词由一个特殊的用户组Public所拥有。顾名思义,数据库中所有的用户都可以使用公有同义词。公有同义词往往用来标示一些比较普通的数据库对象,这些对象常需要引用。公有同义词一般由管理员用户创建及删除。

3)创建私有同义词权限
    grant create synonym to 用户;

4)创建私有同义词
    create synonym 同义词名 for 表;
    create synonym 同义词名 for 视图;

5)私有同义词操作
    select 字段,字段.. from 同义词名;
    update 同义词名 set 字段=值 where 条件;

6)删除私有同义词
    drop synonym 同义词名;

7)创建共有同义词权限
    grant create public synonym to 用户名;
    grant drop public synonym to 用户名;

8)创建共有同义词
    create public synonym 同义词名 for 表;

9)共有同义词操作
    查询数据
    select * from 同义词名;

10)删除共有同义词
    drop public synonym 同义词名;

三十二、索引

1)索引介绍
    索引是建立在数据库表中的某些列的上面,是与表关联的,可提供快速访问数据方式,但会影响增删改的效率.

2)索引分类
    单列索引和组合索引
    唯一索引和非唯一索引

3)什么时候需要创建索引
    1.在经常需要搜索、主键、连接的列上
    2.表很大,记录内容分布范围很广
    3.在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的
    4.在经常使用在WHERE子句中的列上面创建索引

4)什么时候不要创建索引
    1.表经常进行 INSERT/UPDATE/DELETE 操作
    2.表很小(记录超少)
    3.列名不经常作为连接条件或出现在 WHERE 子句中
    4.对于那些定义为text, image和bit数据类型的列不应该增加索引

5)创建索引的准则
    1.如果表里有几百行记录则可以对其创建索引(表里的记录行数越多索引的效果就越明显)。
    2.不要试图对表创建两个或三个以上的索引。
    3.为频繁使用的行创建索引。

6)新建索引
    单列索引
        create index 索引名 on 表名(字段名);
    单列唯一索引
        create unique 索引名 on 表名(字段名);
    组合索引
        create index 索引名 on 表名(字段,字段..);
    组合唯一索引
        create unique 索引名 on 表名(字段,字段..);

7)删除索引
    drop index 索引名;

三十三、序列

1)什么是序列
    序列是oracle提供的一个产生唯一数值型值的机制。通常用于表的主健值,序列只能保证唯一,不能保证连续。

2)序列语法介绍
    Create sequence 序列名
    [increment by n]
    [start with n]
    [maxvalue n][minvalue n]
    [cycle|nocycle]
    [cache|nocache];

    increment by n --表示序列每次增长的幅度;默认值为1.
    start with n --表示序列开始时的序列号。默认值为1.
    maxvalue n --表示序列可以生成的最大值(升序).
    minvalue n --表示序列可以生成的最小值(降序).
    cycle --表示序列到达最大值后,在重新开始生成序列.默认值为 nocycle。
    cache n--允许更快的生成序列.预先生成n个序列值到内存(如果没有使用完,那下次序列的值从内存最大值之后开始;所以n不应该设置太大)

    cycle|nocycle 是否到极限值循环    cache|nocache 存放序列的内存块的大小,默认为20

3)新建序列

    --递增
    create sequence seq_upper
    increment by 1
    start with 1
    maxvalue 10000
    nocycle;

    --递减
    create sequence seq_lower
    increment by -1
    start with 10000
    maxvalue 10000
    minvalue 1
    nocycle;

4)查询当前值
    currval返回序列的当前值.注意在刚建立序列后,序列的currval值为NULL,所以不能直接使用。使用过nextval访问序列后才能使用
    select 序列名.currval from dual;

5)查询下一个值
    nextval 返回序列下一个值;第一次访问时,返回序列的初始值,后继每次调用时,按步长增加的值返回
    select 序列名.nexval from dual;

6)往表中插入一条数据
    insert into 表名(id,字段名) values(序列名.nextval,值);

7)修改序列
    alter sequence 序列名
    maxvalue 9999
    cycle;

8)删除序列
    drop sequence 序列名;

9)sys_guid()方法的使用
    select sys_guid() from dual;

三十四、分区表

1)分区表介绍
    分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中。分区完全对应用透明。Oracle的分区表可以包括多个分区,每个分区都是一个独立的段(SEGMENT),可以存放到不同的表空间中。查询时可以通过查询表来访问各个分区中的数据,也可以通过在查询时直接指定分区的方法来进行查询。

2)分区表的优缺点
    1.由于将数据分散到各个分区中,减少了数据损坏的可能性;
    2.可以对单独的分区进行备份和恢复;
    3.可以将分区映射到不同的物理磁盘上,来分散IO;
    4.提高可管理性、可用性和性能。
    数据量大的表,一般大于2GB;数据有明显的界限划分;对于Long和Long Raw类型列不能使用分区。

3)分区表的分类
    范围分区,散列分区,列表分区
    复合分区(范围-散列分区,范围-列表分区)
    间隔分区和系统分区

4)范围分区语法介绍
    范围分区根据数据库表中某一字段的值的范围来划分分区。

    create table 表名(
        字段,
        字段
        ..
        约束
    )
    partition by range(字段)(
        partition 范围名 values less than (范围值) [tablespace 表空间名],
        partition 范围名 values less than (范围值) [tablespace 表空间名],
        ..
        partition 范围名 values less than (maxvalue) [tablespace 表空间名]
    );

    maxvalue:当分区列值都不在设置的范围内时,新增数据将到这个分区中

5)创建范围分区表
    create table myemp(
           empno number(4) primary key,
           ename varchar2(20),
           hiredate date,
           sal number(7,2),
           deptno number(2)
    )
    partition by range(sal)(
              partition part1 values less than(1000),
              partition part2 values less than(2000),
              partition part3 values less than(3000),
              partition part4 values less than(maxvalue)
    );

//插入数据
    insert into myemp(empno,ename,hiredate,sal,deptno) select empno,ename,hiredate,sal,deptno from emp;

6)范围分区表操作
    查询全部
    select * from myemp;

    查询分区
    select * from myemp partition(part1);

    删除数据
    delete from myemp partition(part1);

7)列表分区表语法介绍
    列表分区明确指定了根据某字段的某个具体值进行分区,而不是像范围分区那样根据字段的值范围来划分的。

    create table 表名(
      字段,
      字段
      ..
      约束
    )
    partition by list(字段)(
              partition part1 values (值),
              ..
              partition partn values (default)
    );

    column_name是以其为基础创建列表分区的列。
    part1...partN是分区的名称。
    值 是对应分区的分区键值的列表。
    default关键字允许存储前面的分区不能存储的记录。

8)创建列表分区表

    create table myemp(
           empno number(2),
           ename varchar2(20),
           sal number(7,2),
           deptno number(2)
    )
    partition by list(deptno)(
              partition part1 values(10),
              partition part2 values(20),
              partition part3 values(30),
              partition part4 values(40),
              partition part5 values(default)
    );

    //插入数据
    insert into myemp(empno,ename,sal,deptno) select empno,ename,sal,deptno from emp;


9)列表分区表操作
    查询全部
    select * from myemp;

    查询分区
    select * from myemp partition(part1);

    删除数据
    delete from myemp partition(part1);

三十五、PL/SQL

1)PL/SQL介绍
    pl/sql:块结构语言,是sql(Structured Query Language)语言的一种扩展,结合了oracle过程语言(procedural language)进行使用。

2)PL/SQL构成
    pl/sql块由三部分构成:声明部分、执行部分、异常部分。

3)PL/SQL语法介绍
    declare
      --变量声明区;
    begin
      --程序主要部分,一般用来执行sql语句或者过程语句
      [exception]
        --异常处理;
    end;

4)PL/SQL中的运算符
    比较运算符
        =   等于   
        <>,!=,~=,^= 不等于 
        <   小于  
        >   大于  
        <=  小于或等于   
        >=  大于或等于   
    算术运算符
         +  加号   
         -  减号  
         *  乘号  
         /  除号  
    赋值运算符
        :=  赋值号 
    关系号
        =>  关系号 
    范围运算符
        ..  范围运算符
    连接运算符
        ||  字符连接符
    逻辑运算符
        is null 是空值  
        between and 介于两者之间  
        in  在一系列值中间 
        and 逻辑与 
        or  逻辑或 
        not 取反  

5)变量
    变量名 类型 [:= 初始值];
    name varchar2(20);
    age number(2) := 20;

6)常量
    变量名 constant 类型 := 初始值;
    papa constant varchar2(20) := ‘啪啪’;

7)属性类型
    %type
    可以用来定义数据变量的类型与已定义的数据变量(表中的列)一致。
    变量名 表名.列名%type;
    name emp.ename%type;

    %rowtype
    与某一数据库表的结构一致(修改数据库表结构,可以实时保持一致);访问方式声明为rowtype的 变量名.字段名。
    变量名 表名%rowtype;
    emp_rowinfo emp%rowtype;

8)输出hello world
    declare
      hi varchar(20) := 'hello world'; 
    begin
      dbms_output.put_line(hi);
    end;


9)条件语句 if..elsif..else..end if

    declare
      testempno number(4) := 7499; -- 7369 7499 7566
      test_sal emp.sal%type;
    begin
      select sal into test_sal from emp where empno = testempno;

      if test_sal < 1000 then
         dbms_output.put_line('努力工作');
      elsif test_sal < 2000 then
            dbms_output.put_line('继续努力工作');
      else 
         dbms_output.put_line('加油!');
      end if;
    end;

    注意:指定顺序执行的语句;主要包括 null语句。null语句:是一个可执行语句,相当于一个占位符或不执行操作的空语句。主要用来提高程序语句的完整性和程序的可读性。

    declare
       test_num number(2) := 10;
    begin
      loop
       test_num := test_num - 1;
       if test_num = 4 then
          null;
       else 
          dbms_output.put_line(test_num);
       end if;
       exit when test_num = 0;
      end loop;
    end;


10)循环语句 loop 

    loop

    exit when 条件;
    end loop;

    declare
      test_num number(3) := 100;
      test_sum number(4) := 0;
    begin
      loop
        test_sum := test_sum + test_num;
        test_num := test_num - 1;
        exit when test_num = 0;
      end loop;
      dbms_output.put_line(test_sum);
    end;


11)循环语句 while loop
    while 条件
    loop
    语句;
    end loop;

    declare
      test_num number(3) := 100;
      test_sum number(4) := 0;
    begin
      while test_num > 0
      loop 
            test_sum := test_sum + test_num;
            test_num := test_num - 1;
      end loop;
      dbms_output.put_line(test_sum);
    end;


12)循环语句for
    for 变量 in [reverse] start .. end
    loop
     语句;
    end loop;

..两点表示范围。
    1..100表示时将从1到100进行循环,起始(例如 1)写前边。
    reverse表示反转,循环时变成从100到1进行。

    declare
      test_sum number(4) := 0;
    begin
      for test_num in 1..100
      loop
          test_sum := test_sum + test_num;
      end loop;
      dbms_output.put_line(test_sum);
    end;

13)异常介绍
    程序会遇到错误或未预料到的事件。一个优秀的程序都应该能够正确处理各种出错情况,并尽可能从错误中恢复。


    cursor_already_open 试图"OPEN"一个已经打开的游标  
    dup_val_on_index 试图向有"UNIQUE"中插入重复的值 
    invalid_cursor 试图对以关闭的游标进行操作  
    invalid_number 在SQL语句中将字符转换成数字失败  
    login_denied 使用无效用户登陆  
    no_data_found 没有找到数据时  
    not_login_on 没有登陆Oracle就发出命令时  
    program_error PL/SQL存在诸如某个函数没有"RETURN"语句等内部问题  
    storage_error PL/SQL耗尽内存或内存严重不足  
    timeout_on_resource Oracle等待资源期间发生超时  
    too_many_rows "SELECT INTO"返回多行时  
    value_error 当出现赋值错误  
    zero_divide 除数为零  

14)异常语法
    Exception
    When 异常类型 then
    语句;
    When others then
    语句;
    15)Sqlcode与sqlerrm介绍
    sqlcode 函数 :返回错误代码
    sqlerrm 函数 :返回错误信息

    declare
      test_result number(20);
    begin
      test_result := 1/0;
      dbms_output.put_line('no error');
      exception
          when zero_divide then
               dbms_output.put_line('can not divide zero');
          when others then
               dbms_output.put_line('no error');
    end;

16)自定义异常
    自定义异常:程序在运行过程中,根据业务等情况,认为非正常情况,可以自定义异常。
    对于这种异常,主要分三步来处理: 
    1、定义相关异常;在声明部分定义相关异常,
        格式:<自定义异常名称>exception;
    2、抛出异常;在出现异常部分抛出异常,
        格式:raise <异常名称>;
    3、处理异常;在异常处理部分对异常进行处理,
        格式:when <自定义异常名称> then ...,
    处理异常也可以使用
    raise_application_error(error_number,error_message)存储过程进行处理,其中参数error_number取值为-20999~-20000的负整数,参数error_message为异常文本消息。

    declare
      test_comm emp.comm%type;
      comm_exception exception;
    begin
      select nvl(comm,0) into test_comm from emp where empno = 7499;
      if test_comm > 1000 then
         dbms_output.put_line('this is over 1000');
      else 
         raise comm_exception;
      end if;

      exception
         when comm_exception then
              dbms_output.put_line('comm can not lower 1000');
         when others then
              dbms_output.put_line('comm is normal');
    end;

三十六、游标

1)什么是游标
    游标是映射在结果集中一行数据上的位置实体,使用游标,便可以访问结果集中的任意一行数据了,将游标放置到某行后,即可对该行数据进行操作;从上向下依次迭代结果集。
2)游标的语法
    cursor 游标名 is 查询语句;
3)游标操作
    打开游标
    open 游标名;
    关闭游标
    close 游标名;
    赋值
    fetch 游标名 into 变量1,变量2,...变量n;
    fetch 游标名 into 行对象;


4)游标属性
    %notfound --如果FETCH语句失败,则该属性为"true",否则为"false";  
    %found --如果FETCH语句成果,则该属性为"true",否则为"false"; 
    %rowcount --返回游标当前行的行数;  
    %isopen --如果游标是开的则返回"true",否则为"false";  


5)游标使用
    1、使用游标显示员工表中所有的员工姓名、工作和工资

    declare
      emp_info emp%rowtype;
      cursor select_emp_info is select * from emp;
    begin
      open select_emp_info;
      loop
         fetch select_emp_info into emp_info;
         dbms_output.put_line('员工姓名' || emp_info.ename);
                    exit when select_emp_info%notfound;
                 end loop;
    end;

2、使用游标显示指定部门下的所有的员工姓名、工作和工资

    declare
      emp_info emp%rowtype;
      cursor cur_emp_info(dno emp.deptno%type) is select * from emp where deptno = dno;
    begin
      open cur_emp_info(20);
      loop
           fetch cur_emp_info into emp_info;
           dbms_output.put_line('员工姓名:'||emp_info.ename);
           exit when cur_emp_info%notfound;
      end loop;
    end;

3、使用游标按员工的工种涨工资,总裁800,经理600,其他人员300
    declare
      cursor cur_emp_info is select * from emp;
      emp_info emp%rowtype;
    begin
      open cur_emp_info;
      loop    
              fetch cur_emp_info into emp_info;
              exit when  cur_emp_info%notfound;
              if 'PRESIDENT' = emp_info.job then
                 update emp set sal = sal+800 where empno = emp_info.empno;
              elsif 'MANAGER' = emp_info.job then
                 update emp set sal = sal+500 where empno = emp_info.empno;
              else
                 update emp set sal = sal+300 where empno = emp_info.empno;
              end if;
      end loop;
      close cur_emp_info;
      commit;
    end;

6)隐式游标

    当执行一个SQL语句时,Oracle会自动创建一个隐式游标,隐式游标主要处理DML语句,该游标的名称是sql。隐试游标不能进行"open" ,"close","fetch"这些操作。

    begin
          update emp set comm = comm + 300 where empno = 7369;
          if sql%notfound then
             dbms_output.put_line('员工不存在');
          else 
             dbms_output.put_line('对应的员工数:' || sql%rowcount);
          end if;
    end;

三十七、存储过程

1)什么是存储过程
    存储过程是命名的pl/sql程序块,封装数据业务操作,具有模块化、可重用、可维护、更安全特点;并且可以被程序调用。

2)什么时候用存储过程[]

3)存储过程分类
    一般有4类型的存储过程,分别为不带参数、带输入参数、带输出参数、带输入输出参数。

4)存储过程语法

    create or replace procedure 过程名[参数列表] as|is
    [局部变量声明]
    begin
           可执行语句;
           exception 异常语句;
    end;

    or replace:如果系统已存在该存储过程,将被替换 
    参数列表:参数不需要声明长度,可选
    参数变量的类型:in 为默认类型,表示输入; out 表示只输出;in out 表示即输入又输出;

    is 和 as 没有区别

5)不带参数的

    create or replace procedure pro_onetest as
    begin
        dbms_output.put_line('this is the first procedure');   
    end;


  create or replace procedure test04
  as
  t_name emp.ename%type;
  t_sal emp.sal%type;
  begin
        select ename,sal into t_name,t_sal from emp where empno = 7369;
        dbms_output.put_line(t_name);
        dbms_output.put_line(t_sal);
  end;


// 调用存储过程
    begin
        pro_onetest();
    end;

6)带输入参数

    create or replace procedure pro_emp_output(p_empno in emp.empno%type) as
    test_name emp.ename%type;
    begin
        select ename into test_name from emp where empno = p_empno;
        dbms_output.put_line(test_name);
    end;

    begin
        pro_emp_output(7369);
    end;


7)带输出参数

     create or replace procedure test05(
            t_comm out emp.comm%type
     )as
     begin
           select comm into t_comm from emp where empno = 7499;
     end;

    //调用方式
     declare
       test_com emp.comm%type;
     begin
     test05(test_com);
     dbms_output.put_line('test_com='||test_com);
     end;

8)带输入输出参数

     create or replace procedure test05(
            t_empno emp.empno%type,
            t_comm out emp.comm%type
     )as
     t_name emp.ename%type;
     t_sal emp.sal%type;
     begin
           select ename,sal,comm into t_name,t_sal,t_comm from emp where empno = t_empno;
           dbms_output.put_line(t_name);
           dbms_output.put_line(t_sal);
     end;

    //调用方式
     declare
       test_com emp.comm%type;
     begin
     test05(7369,test_com);
     dbms_output.put_line('test_com='||test_com);
     end;

9)查询所有的存储过程
    select * from user_procedures;

10)删除存储过程
    drop procedure 过程名;

11)查询存储过程的具体内容
    select * from all_source where type = 'PROCEDURE' AND owner = 'SCOTT';

三十八、存储函数

1)什么是存储函数
    存储函数与过程不同的是,存储函数有return语句;一般情况下如果在需要一个返回值时可使用存储函数。

2)存储函数语法介绍
    create or replace function 函数名[参数列表] return 数据类型
    is|as
    [局部变量声明]
    begin
           可执行语句;
           exception 异常;
           return 值;
    end;

    变量的类型:in 为默认类型,表示输入; out 表示只输出;in out 表示即输入又输出;

    is 和 as 没有区别

3)无参存储函数
    create or replace function fun_one return varchar2 is
    begin
           return 'hello world';
    end;

    declare
           str varchar2(20);
    begin
           str := fun_one();
           dbms_output.put_line(str);
    end;

4)有输入参数的存储函数

    create or replace function fun_one(test_empno in emp.empno%type) return varchar2 
    as
    test_ename emp.ename%type;
    begin
           select ename into test_ename from emp where empno = test_empno;       
           return test_ename;
    end;

    //调用方式
    declare
           str varchar2(20);
    begin
           str := fun_one(7369);
           dbms_output.put_line(str);
    end;

5)有输入输出的参数函数

    create or replace function fun_get_sal(test_empno in emp.empno%type,test_name out emp.ename%type) return number
    as
    test_sal emp.sal%type;
    begin
             select ename,sal into test_name,test_sal from emp where empno = test_empno;
             dbms_output.put_line(test_name);
             return test_sal;
    end;

    declare
    p_sal emp.sal%type;
    p_ename emp.ename%type;
    begin
          p_sal := fun_get_sal(7499,p_ename);
          dbms_output.put_line(p_sal);
    end;


6)查询所有的存储函数
    select * from user_procedures;

7)查看存储函数具体内容
    select * from user_source;

8)删除存储函数
    drop function 函数名;

三十九、程序包

1)什么是程序包
    包(Package)是一组相关过程、函数、变量、常量、类型和游标等PL/SQL程序设计元素的组合。包具有面向对象设计的特点,是对这些PL/SQL程序设计元素的封装。

2)程序包组成
    包的包括两部分:定义一个包(包头)、实现一个包(包体);只有当定义包后才能实现包体.其中包体中的函数名与过程名须和包头中定义的函数、过程一样。

3)程序包注意
    1、包和包体必须有相同的名字;
    2、包的开始没有begin语句,与存储过程和函数不同;
    3、在包头部分定义函数和过程的名称和参数,具体实现在包体中定义;
    4、在包体内声明常量、变量、类型定义、异常、及游标时不使用declare;
    5、包体内的过程和函数的定义不要create or replace语句;
    6、包定义和包体两者分离。

4)程序包有什么用
    通过包可以分类管理存储过程和函数。

5)创建包头语法
    create or replace package 包名 is|as
           --公共类型和对象
           --子程序说明
    end;

    create or replace package 包名 as
           --私有自定义类型(包内可用)
           type 类型名 is 类型;
           --私有常量(包内可用)
           常量名 constant 类型 := 值;
           --私有变量(包内可用)
           常量名 类型;
           --存储过程
           procedure 
           --存储函数
           function
    end;

6)创建包头

    create or replace package p_one_test as
           --定义存储过程
           procedure pro_pro_one(p_empno emp.empno%type); 
           --定义函数
           function pro_fun_one(p_empno emp.empno%type) return varchar2;
    end;


7)实现包体
    create or replace package body p_one_test as

           test_ename emp.ename%type;


           procedure pro_pro_one(p_empno emp.empno%type) as
           begin
                 select ename into test_ename from emp where empno = p_empno;
                 dbms_output.put_line(test_ename);
           end;


           function pro_fun_one(p_empno emp.empno%type) return varchar2 as
           begin
                 select ename into test_ename from emp where empno =  p_empno;
                 return test_ename;
           end;

    end;

8)调用包
    declare
           test_ename emp.ename%type;
    begin
           p_one_test.pro_pro_one(7369);
           test_ename := p_one_test.pro_fun_one(7369);
           dbms_output.put_line(test_ename);
    end;

9)删除包
    drop package 包名;

四十、触发器

1)什么是触发器
    触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行。即触发器是当某个事件发生时自动地隐式运行。并且,触发器不能接收参数。

2)触发器语法
    create or replace trigger 触发器名
    before|after
    insert|update|delete [of 列名] on 表名
    [for each row]
    <pl/sql块>

    关键字"before"在操作完成前触发;"after"则是在操作完成后触发;
    关键字"for each row"指定触发器每行触发一次,若不指定则为表级触发器.
    关键字"of <列名>" 不写表示对整个表的所有列.
    pl/sql块中不能使用commit;

    :new --为一个引用最新的行值;
    :old --为一个引用以前的行值; 
    这些变量只有在使用了关键字 "for each row"时才存在.
    且update语句两个都有,
    而insert只有:new ,
    delect 只有:old;

3)行级触发器

4)表级触发器

5)开启禁用触发器

四十一、数据字典

    

四十二、闪回


四十三、数据库备份与恢复


四十四、数据库性能优化


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容