本章开始介绍目前市场上非常流行. 功能非常强大的数据库管理系统 ---- Oracle , 内容是按照Oracle的步骤来组织的.首先介绍 Oracle 基础知识,包括Oracle简介,基本概念,安装Oracle数据库,其次介绍连接Oracle服务器时如何正确的配置监听器LISTENER 和本地网络服务名,并讲解使用SQL语言对完成对数据的基本操作,以及常用函数的介绍.
SQL语言查询我们已经学习了以下三种方法
联合查询(UNION)
表连接查询(JOIN)
子查询
请分别介绍这三种查询各自特点,以及应该注意的事项:
内连接:内连接返回两个关联表中所有满足连接条件的记录。语法是 inner join on
外连接:不仅返回满足连接条件的记录,还将返回不满足连接条件的记录。分两种:左外连接和右外连接.左外连接:以左表为标准,若右表不满足,取值为null, LEFT OUTER JOIN
右外连接:以右侧表为标准,若左侧表不满足,则取值为null RIGHT OUTER JOIN
全外连接:是指除了返回两个表中满足连接条件的记录,还会返回不满足连接条件的所有其它行 。即是左外连接和右外连接查询结果的总和 FULL OUTER JOIN
自连接:是一种特殊的连接查询,数据的来源是一个表.树状结构的表用自连接.
联合查询的特点 以及注意事项相当于把多个查询结果给复制到另一种表中
联合查询:可合并多个相似的选择查询的结果集。等同于将一个表追加到另一个表,从而实现将两个表的查询组合到一起,使用谓词为UNION或UNION ALL。
注意事项:查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语句中定义。
要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。
通过集合操作符连接各个查询具有相同的列数,而且对应列的数据类型必须兼容,查询结果的列标题必须为第一个select语句
表连接查询:特点在有主外键关联关系的表间建立,并将连接条件设定为有关系的列
注意事项:注意连接条件,注意主外键之间的关系
子查询:当一个查询是另一个查询的条件时,称之为子查询 也就是说当我们查询的条件不是一个确定的值,而是来自于另外一个查询的结果的时候
注意事项:
一个子查询必须放在圆括号中。
将子查询放在比较条件的右边以增加可读性。
可以在where、select、having、from之后使用子查询
oracle中不可以在group by后使用子查询
from后的子查询:子查询返回的也是一个新表
主查询与子查询的可以不是同一个表,只要子查询查询的结果在主查询可以使用即可。
一般先执行子查询 再执行主查询,所以子查询语句不能太多,而且不能过于复杂
单行子查询只能使用单行操作符,多行子查询只能使用多行操作符
Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的 适应高吞吐量的数据库解决方案。
Oracle数据特点
1、完整的数据管理功能:
2、完备关系的产品:
3、分布式处理功能:
4、用ORACLE能轻松的实现数据仓库的操作。这是一个技术发展的趋势,不在这里讨论。
优点
■ 可用性强
■ 可扩展性强
■ 数据安全性强
■ 稳定性强
通常情况下"数据库",并不仅指物理的数据集合,还是一系列物理文件的集合
(数据文件,控制文件,联机日志,参数文件等)以及数据库管理系统,即数据库是物理数据、内存、操作系统进程的组合体
实例是访问Oracle数据库所需的一部分计算机内存和辅助处理后台进程,是由进程和这些进程所使用的内存(SGA)所构成一个集合,其实就是用来访问和使用数据库的一个进程
,只存在于内存中,就像Java中new出来的实例对象
一样。
解释SGA:
SGA:
共享池:
1.库高速缓存:运用独特算法管理sql语句的存储和使用
2.数据字典的高速缓存:包含数据库文件,表,索引,列,用户,权限和其他的数据库对象相关信息
数据缓冲区:存储已经检索到的数据副本,提高读取和更新数据的性能
日志缓冲区:记录数据库的重新构建和更改信息
数据库名就是一个数据库的标识,就像人的身份证号一样,在数据库安装或创建完成之后,参数DB_NAME被写入参数文件init.ora.xxxxxxx之中。
在创建数据库时就应考虑好数据库名,并且在创建完之后,数据库名不宜修改,即使要修改也会很繁琐。因为,数据库名还被写入控制文件中,控制文件是以二进制型式存储的,用户无法修改控制文件的内容。假设用户修改了参数文件中的数据库名,但是在Oracle启动时,由于参数文件中的DB_NAME与控制文件中的数据库名不一致,导致数据库启动失败,将返回ORA-01103错误。
查询当前数据库名 :
1)-select name from v$database;
2)-show parameter db
3)-查看参数文件(init.ora.xxxxx)
在分布式数据库系统中,不同版本的数据库服务器之间,不论运行的操作系统是unix或是windows,各服务器之间都可以通过数据库链路进行远程复制,数据库域名主要用于分布式环境中的复制。
什么时候使用域名 :
用于区分一个数据库的内部标识,在安装数据库、创建新数据库等等都需要使用数据库名
全局数据库名=数据库名+数据库域名,使数据库的取名在整个网络环境中唯一
Oracle是通过表空间来存储物理表的,一个数据库实例可以有N个表空间,一个表空间下可以有N张表。有了数据库,就可以创建表空间;表空间是数据库的逻辑划分,每个数据库至少有一个表空间(SYSTEM表空间);为了便于管理和提高运行效率,可以使用一些附加表空间来划分用户和应用程序。例如:USER表空间供一般用户使用,RBS表空间供回滚段使用,一个表空间只能属于一个数据库。
用户在数据库中建立的所有内容都被存储到表空间中,创建数据库时会自动创建若干表空间
通常,数据文件的扩展名是.dbf , 是用于存储数据库数据的文件,如存储数据库表中的记录,索引,存储过程,视图,数据字典定义等.对于数据库操作中产生的一些临时数据,以及为保证事务重做所必需的数据也有专门的数据文件负责存储.
一个数据文件可能存储很多表的数据,而一个表的数据也可能存放在多个数据文件中,即数据表和数据文件不存在一对一的关系.
通常,控制文件的扩展名是.ctl , 是一个二进制文件 . 控制文件中存储的信息很多,其中包括数据文件和日志文件的名称和位置. 控制文件是数据启动以及运行所必需的文件.当Oracle读写数据时,要根据控制文件的信息查找数据文件.
由于控制文件的重要性,因此一个数据库至少有一个以上的控制文件.
通常 , 日志文件的扩展名是 .log,它记录了数据的所有更改信息,并提供了一种数据恢复机制,确保在系统崩溃或其他意外出现后重新恢复数据库.
在Oracle数据库中,日志文件是成组使用的 , 每个日志文件组可以有一个或多个日志文件.在工作过程中,多个日志文件组之间循环使用,当一个日志文件写满后,会转向下一个日志文件组.
模式是数据库对象(如表,索引等,也称模式对象)的集合.Oracle 会为每一个数据库用户创建一个模式,此模式为当前用户所拥有,和用户具有相同的名称.
完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例。如图所示:
数据库 : 是一系列物理文件的集合(数据文件,控制文件,联机日志,参数文件等)
Oracle数据库实例 则是一组Oracle后台进程/线程以及在服务器分配的共享内存区。
在启动Oracle数据库服务器时,实际上是在服务器的内存中创建一个Oracle实例(即在服务器内存中分配共享内存并创建相关的后台内存),然后由这个Oracle数据库实例来访问和控制磁盘中的数据文件。
Oracle有一个很大的内存快,成为全局区(SGA)
数据库是数据集合。Oracle是一种数据库管理系统,是一种关系型的数据库管理系统
通常情况了我们称的“数据库”,并不仅指物理的数据集合,它包含物理数据、数据库管理系统。也即物理数据、内存、操作系统进程的组合体。
全局数据库名:就是一个数据库的标识,在安装时就要想好,以后一般不修改,修改起来也麻烦,因为数据库一旦安装,数据库名就写进了控制文件,数据库表,很多地方都会用到这个数据库名。
启动数据库:也叫全局数据库,是数据库系统的入口,它会内置一些高级权限的用户如SYS,SYSTEM等。
我们用这些高级权限账号登陆就可以在数据库实例中创建表空间,用户,表了。
用Oracle官方描述:实例是访问Oracle数据库所需的一部分计算机内存和辅助处理后台进程,是由进程和这些进程所使用的内存(SGA)所构成一个集合。其实就是用来访问和使用数据库的一块进程,它只存在于内存中。就像Java中new出来的实例对象一样。
我们访问Oracle都是访问一个实例,但这个实例如果关联了数据库文件,就是可以访问的,如果没有,就会得到实例不可用的错误。
实例名指的是用于响应某个数据库操作的数据库管理系统的名称。它同时也叫SID。实例名是由参数instance_name决定的。我们访问Oracle都是访问一个实例,但这个实例如果关联了数据库文件,就是可以访问的,如果没有,就会得到实例不可用的错误。实例名指的是用于响应某个数据库操作的数据库管理系统的名称。它同时也叫SID。实例名是由参数instance_name决定的。
表空间中存储的对象叫段,比如数据段,索引段,段由区组成,区是磁盘分配的最小单位。
段的增大是通过增加区的个数来实现的。每个区的大小是数据块大小的整数倍,区的大小可以不相同;
数据块是数据库中最小的I/O单位,同时也是内存数据缓冲区的单位,及数据文件存储空间单位。
区是磁盘空间分配的最小单位
返回顶部
Oracle服务器
所谓oracle服务器是一个数据库管理系统,它包括一个oracle实例(动态)和一个oracle数据库(静态)。
Oracle实例
是一个运行的概念(如操作系统的进程),提供了一种访问oracle数据库的方式,始终打开一个,并且只能打开一个oracle数据库,oracle实例有SGA和一些后台服务进程组成,在后台服务进程当中,DBWn PMON CKPT LGWR SMON是必备的后台进程,而ad queue,rac,shared server,ad replication则是可选的,之所以可选,要们是因为离开它oracle也能正常运行,要么是一些高级的功能才可以用得到。
oracle数据库是一个被统一处理的的数据的集合,从物理角度来看包括三类文件数据文件,控制文件,重做日志文件。从逻辑角度来看,oracle数据库至少包含一个表空间,表空间至少包含一个段,段由区做成,区有块组成。需要注意的是表空间可以包含若干个数据文件,段可以跨同一个表空间的多个数据文件,区只能在同一个数据文件内。
数据库 磁盘上存储的数据的集合 在物理上表现为数据文件、日志文件和控制文件等,在逻辑上以表空间形式存在 必须首先创建数据库,然后才能使用Oracle
数据库实例 每个启动的数据库都对应一个数据库实例,由这个实例来访问和控制数据库 为了运行数据库,Oracle系统所运行的所有进程和分配的内存结构的组合体
数据文件 扩展名是.DBF,用于存储数据库数据的文件数据库表和数据文件不存在一对一对应关系
控制文件 扩展名是.CTL,是数据库启动及运行所必需的文件 默认包含3个控制文件,各个控制文件内容相同
日志文件 扩展名是.LOG,它记录了对数据的所有更改信息多个日志文件组之间循环使用
SGA:共享池:
1.库高速缓存:运用独特算法管理 sql语句的存储和使用
2.数据字典的高速缓存:包含数据库文件,表,索引,列,用户,权限和其他的数据库对象相关信息
数据缓冲区: 存储已经检索到的数据副本,提高读取和更新数据的性能
日志缓冲区: 记录数据库的重新构建和更改信息
PGA(程序缓存区)与SGA(系统全局区)
PGA区,用来存储这个用户会话的相关内容。当这个用户会话终止时,数据库系统会自动释放这个PAG区所占用的内存。PGA区对于数据库的性能有比较大的影响,特别是对于排序操作的性能
SGA的主要用途就是为不同用户之间的进程与服务进程提供一个交流的平台,另外有一个重要的作用就是各种数据库的操作主要就是在这个SGA区内完成。
做个形象的比喻,SGA就好像是操作系统上的一个共享文件夹,不同用户可以以此为平台进行数据方面的交流。而PGA就好像是操作系统上的一个私有文件夹,只有这个文件夹的所有者才能够进行访问,其他用户都不能够访问。
虽然程序缓存区不像其他用户的进程开放,但是这个内存区仍然肩负着一些重要的使命,如数据排序、权限控制等等都离不开这个内存区。
- 用户进程向oracle发送一条sql语句
- oracle接受到用户进程的请求之后,会先启用
服务器进程
服务器进程
就会与用户进程
就组成了一个session(会话)服务器进程
就会处理用户请求- 处理请求时,首先开启一块内存(PGA),将用户信息(sql语句)存放在
PGA区
(Program Global Area),注意:每个用户进程都有一个PGA区(存放用户的数据排序、权限控制等等)服务器进程
就开辟了内存后就要开始执行SQL语句了.这时候就需要去访问SGA
.- 访问
SGA
,首先去共享池
里解析SQL语句,得到执行计划,然后按照执行计划去数据缓冲区
查找数据.
- 如果
数据缓冲区
里没有,服务器进程
就直接去磁盘里面读数据到数据缓冲区
.- 如果
数据缓冲区
里读到了数据,用户需要修改数据块,那么就会在数据缓冲区
里修改数据块
.
- 修改数据块后会产生
redo log
,日志缓冲区
会产生响应的重做项- 如果用户发出commit的提交,
日志缓冲区
会通过LGWR
进程将数据写到磁盘上- 如果用户发出了checkpoint检查点,数据会被
DBWN
进程会将修改了的脏数据(脏数据就是正在使用,而没有写入到数据库文件中数据)写入磁盘上.
用户进程
执行一个查询语句如select * from emp where empno=7839
用户进程
和服务器进程
建立连接,把该用户进程的信息存储到PGA
的UGA中- 语句经过
PGA
处理后传递给实例instance- 实例instance中的
共享池
处理这条语句
- 库缓冲区去判断语句如何分析–软分析(快)或硬分析(慢)
- 根据cbo得到执行计划,准备去执行语句.(CBO和RBO是ORACLE提供的两种优化器)
- 查询语句中的对象(emp表和行)存放在那个表空间,指定的行放在那个
数据块
里,需要到数据字典缓冲区得到这些信息。- 开始执行
- 如何执行?在内存中执行
- 判断在
数据缓冲区
中是否缓存了需要的数据块
。
- 如果是,在内存读取数据得到需要的行的结果返回给用户,用户看到执行的结果。
- 如果不是,则服务器进程把块从磁盘读入到
数据缓冲区
中缓存下来,然后undo缓存块会对该块做镜像,然后读镜像中的数据得到行的结果返回给用户,用户看到执行的结果。
用户进程
执行一个update语句:UPDATE emp set sal=10 WHERE id=1234
用户进程
和服务器进程
建立连接,把该用户进程的信息存储到PGA
的UGA中- 语句经过PGA处理后传递给实例instance
- 实例instance中的
共享池
处理这条语句
- 库缓冲区去判断语句如何分析–软分析(快)或硬分析(慢)
- 根据cbo得到执行计划,准备去执行语句.(CBO和RBO是ORACLE提供的两种优化器)
- 查询语句中的对象(emp表和行)存放在那个表空间,需要修改的行放在那个
数据块
里?需要到数据字典缓冲区得到这些信息。- 开始执行
- 如何执行?在内存中执行
- 判断在
数据缓冲区
中是否缓存了需要修改的块。
- 如果是,直接在内存中操作。
- 如果不是,则服务器进程把块从磁盘读入到
数据缓冲区
缓存下来,然后undo缓存块会对该块做镜像,然后对内存中的数据块
做修改操作。- 由于
数据块
发生了修改/变化,redo日志缓冲区
会记录数据块
修改的操作信息,同时,会将修改之前的数据放在undo块镜像,修改之后的数据放在undo块镜像。- 提交的数据要写入磁盘,没有提交的不写入磁盘。如果执行了commit,
数据缓冲区
的undo的块数据就会标记已经提交。
redo
是记录日志用的。undo
是记录数据的备份用的。简单举个例子说明(实际过程比这要复杂的多):
- 当你发出一条update语句后,oracle先将更改前后信息写进
redo
(当满足一定条件后由日志写进程写入日志文件)- 然后将更新前得数据镜像copy到
undo
中。- 用户rollback后,oracle 将undo中的数据覆盖回去.用户commit后,oracle可以根据
redo
的信息进行数据恢复。
1) :database write--数据写入 DBWR
作用:把SGA中被修改的数据同步到磁盘文件中。保证Buffer Cache中有足够的空闲数据块数量。
PS:如果LGWR出现故障,DBWR不会听从CKPT命令罢工,因为Oracle在将数据缓存区数据写到磁盘前,会先进行日志缓冲区写进日志文件的操作,并耐心的等待其先完成,才会去完成这个内存刷到磁盘的动作,这就是所谓的凡事有记录。
触发条件:
1、检查点CKPT
2、一个服务进程在设定的时间内没有找到空闲块
3、每三秒自动唤醒一次。
设置:DB_WRITER_PROCESS用来定义DBWn进程数量。(commit命令只是把记录修改写入日志文件,不是把修改后的数据写入数据文件)
2) :log write:LGWR--日志文件写入
(劳模,很重要很忙碌的一个进程)
作用:把log buffer中的日志内容写入联机的日志文件中,释放log用户buffer空间。
触发条件:
1、用户发出commit命令。(在oracle中称为快速提交机制(fast commit)):把redo log buffer中的记录写入日志文件,写入一条提交的记录
2、三秒定时唤醒。
3、日志缓冲区log buffer超过1/3,或日志数量超过1M。
4、DBWR进程触发:DBWn视图将脏数据块写入磁盘先检测他的相关redo记录是否写入联机日志文件,如果没有就通知LGWR进程。在oracle中成为提前写机制(write ahead):redo记录先于数据记录被写入磁盘
5、联机日志文件切换也将触发LGWR。
3):checkpoint:CKPT-检查点事件
作用:维护数据库一致性状态。检测点时刻数据文件与SGA中的内容一致,这不是一个单独的进程,要和前两个进程一起工作呦。DBWR写入脏数据,同时触发LGWR进程。
CKPT更新控制文件中的检查点记录。通过设置某参数调整来控制CKPT的触发时间。参数是FAST START MTTR TARGET。
触发条件:日志切换(log switch)会触发检查点。
4):process monitor:PMON--维护用户进程 进程监控器
作用:
1、发现用户进程异常终止,并进行清理。释放占用资源。(清理异常终止用户使用的锁)
2、向监听程序动态的注册实例。
触发条件:定时被唤醒,其他进程也会主动唤醒它。
5):system monitor:SMON--实例维护进程 系统监控器
作用:
1、负责实例恢复,前滚(Roll Forward)恢复到实例关闭的状态,使用最后一次检查点后的日志进程重做。这时包括提交和未提交的事务。打开数据库,进行回滚(Roll Back):回滚未提交的事务。(oracle承诺commit之后数据不会丢失,现在我们可以大致的了解是如何实现这个承诺,以及在数据的安全性和数据库性能之间的平衡选择。)
2、负责清理临时段,以释放空间
触发条件:定期被唤醒或者被其他事务主动唤醒。
Oracle安装包下载位置:https://www.oracle.com/database/technologies/oracle-database-software-downloads.html#11g
第一次安装Oracle时,请不要急于单击"下一步"
按钮,一定要仔细阅读每个安装页中的说明文档。说明文档可以帮助我们更好的了解Oracle的相关知识。
详细的安装过程请参照课本上的附录1。
11g安装完成之后,可以使用web方式管理工具,访问https://localhost:1158/em/
进入管理界面,账号密码可以输入刚刚设置的system和对应的密码;
12c 安装完成之后,可以使用web方式管理工具,访问 https://localhost:5500/em/
进入管理界面,账号密码可以输入刚刚设置的system和对应的密码。
Windows操作系统下,Oracle服务的启动与关闭是以后台服务的方式来管理的.通过后台服务管理界面,可以进行Oracle实例的启动与关闭,Oracle监听的启动与关闭以及其他服务的启动与关闭.在Windows中,Oracle的每个实例都作为一项服务来启动.服务是在Windows注册表中注册的可执行进程,由Windows操作系统管理.
下面介绍Oracle常用的两个服务:
(1) OracleServiceSID服务是Oracle数据库服务.此服务是对应名为SID(系统标识符)的数据库实例创建的,其中SID是安装在Oracle时输入的数据库名称.该服务默认是自启动的,可设置为手动启动,可自动启动数据库,Windows中启动命令为:net start OracleServiceSID(实例名)
, 例如:net start OracleServiceORCL
,如果此服务未启动,本地客户端如SQL Plus连接数据库服务器时就会出现错误,因此该服务必须启动
(2) OracleOraDb_TNSListener 服务是监听器服务.此服务是Oracle服务器器端的监听程序,要连接远程数据库服务器,客户端必须先连接驻留在数据库服务器的监听进程.监听器接受从客户端发出的请求,然后将请求传递给数据库服务.一旦建立了连接,客户端与数据库服务就能直接通信.监听器监听并接受来自客户端应用程序的连接请求,该服务只有在数据库需要远程访问的时候才需要.Windows下启动监听服务的命令:lsnrctl start
.
在安装Oracle数据库配置全局数据库时,监听程序已经默认配置好了,实际上我们不用再配置监听程序,为了让大家更好的掌握"监听程序配置"
,可以手动添加一个.参照课本附录2
当创建一个新的数据库时,Oracle 将创建一些默认数据库用户,如sys,system和scott等(注意Oracle 12c之后不再提供默认的scott用户),可以使用这些用户连接数据库.sys 和 system用户都是Oracle的系统用户,都使用SYSTEM表空间,而SYS拥有更大的权,区别还有:
SYS用户 | SYSTEM用户 | |
---|---|---|
地位 | Oracle的一个超级用户 | Oracle默认的系统管理员,拥有DBA权限 |
作用 | 主要用来维护系统信息和管理实例 | 通常用来管理Oracle数据库的用户、权限和存储等 |
登录身份 | 只能以SYSDBA或SYSOPER角色登录 | 只能以Normal方式登录 |
想要连接数据库,可以使用Oracle自带的SQL*Plus和SQL Developer工具,也可以使用第三方提供的PL/SQL Developer工具,也可以在cmd窗口使用命令登录.
命令如下:
-- 普通用户登录
sqlplus username/password
-- 如:普通用户登录
sqlplus scott/tiger
-- 以sysdba的方式登录
sqlplus username/password as sysdba
-- 如:sysdba用户登录
sqlplus system/123456 as sysdba
-- 用户指定登录orcl数据库
sqlplus username/password@net_service_name
-- 用户指定登录orcl数据库
sqlplus scott/tiger@orcl
Windows+R 运行 sqlplus 命令,即可打开与Oracle数据库进行交互的客户端工具,输入对应的用户名,密码即可登录.可使用如下命令切换用户:
-- (权限,若是普通用户可以不用填写sysdba)
conn sys/123456 as sysdba
执行show命令:
-- (显示当前用户名)
show user
执行查询命令:
-- (查询scott用户的emp表)
select * from scott.emp;
若在12c中,执行上面的查询命令,会报错:ORA-00942: 表或视图不存在.这是因为在12c中不再提供scott用户,可以先创建PDB
数据库(可参照12c创建pdb的步骤),然后创建普通的scott用户 , 或者使用命令直接在CDB
数据库中创建scott用户:
create user c##scott identified by tiger;
注意在12c中若创建全局用户必须以c##
开头,如果一定要创建scott用户,可以在12c中先创建pdb
数据库,步骤可参考创建pdb数据库,创建完pdb数据库之后,就可以创建scott用户了
为c##scott
用户授权:
-- 为c##scott用户授权
grant connect,resource,unlimited tablespace to c##scott container=all;
设置用户的空间:
alter user c##scott default tablespace users;
alter user c##scott temporary tablespace temp;
切换到c##scott
用户下:
connect c##scott/tiger
-- (显示当前用户)
show user
找到表的emp的sql文件,文件位置:D:\app\Administrator\product\12.2.0\dbhome_1\rdbms\admin\scott.sql
,去掉
与创建表无关的语句,执行如下命令:
-- (执行sql文件)
@D:\app\Administrator\product\12.2.0\dbhome_1\rdbms\admin\scott.sql;
1. 右击连接,如图:
看到状态为成功,代表连接成功!
返回顶部
Oracle常用的数据类型:
CHAR类型,定长字符串,会用空格填充来达到其最大长度。非NULL的CHAR(12)总是包含12字节信息。CHAR字段最多可以存储2,000字节的信息。如果创建表时,不指定CHAR长度,则默认为1。另外你可以指定它存储字节或字符,例如 CHAR(12 BYTYE) CHAR(12 CHAR).一般来说默认是存储字节
注意:数据库的NLS_CHARACTERSET 为AL32UTF8,即一个汉字占用三到四个字节。如果NLS_CHARACTERSET为ZHS16GBK,则一个字符占用两个字节。
这是一个包含UNICODE格式数据的定长字符串。NCHAR字段最多可以存储2,000字节的信息。它的最大长度取决于国家字符集。
NCHAR 和 CHAR 区别在于NCHAR用来存储Unicode字符集类型,即双字节字符数据.例如:我们定义CHAR(1) 和 NCHAR(1) 类型的两个字段,字段长度为1字节和1个字符(2字节),分别插入’a’ 和 ‘a’ 是没有问题的,但是占用的字节数分别是1和2.如果分别插入’的’和’的’,则前者无法正常插入,后者可以.
NVARCHAR2 与 NCHAR 类似,在使用上,NVARCHAR2存储需要国际化的可变字符串.
Oracle中不建议使用VARCHAR数据类型。使用VARCHAR2数据类型。
变长字符串,与CHAR类型不同,它不会使用空格填充至最大长度。VARCHAR2最多可以存储4,000字节的信息。
这是一个包含UNICODE格式数据的变长字符串。 NVARCHAR2最多可以存储4,000字节的信息。
提示:
VARCHAR2 数据类型也可以像NVARCHAR2数据类型一样根据定义的长度存储相应的汉字个数.声明如下:VARCHAR2(10 CHAR)的含义是存储10个字符.至于一个字符占几个字节,并不关心,也就是说可以存储10个汉字.
NUMBER(P,S)是最常见的数字类型,可以存储正数,负数,零,定点数和精度为38位的浮点数.
P 是Precision的英文缩写,即精度缩写,表示有效数字的位数,最多不能超过38个有效数字
S是Scale的英文缩写,可以使用的范围为-84~127。Scale为正数时,表示从小数点到最低有效数字的位数,它为负数时,表示从最大有效数字到小数点的位数.
例如: 在表Emp中的Sal列的定义如下:
Sal NUMBER(6,2):
表示Sal列中的数据,整数位最大为4位,小数位最大位数是2位,也就是最大取值:9999.99。
INTEGER类型
INTEGER是NUMBER的子类型,它等同于NUMBER(38,0),用来存储整数。若插入、更新的数值有小数,则会被四舍五入。
DATE是最常用的数据类型,日期数据类型存储日期和时间信息。虽然可以用字符或数字类型表示日期和时间信息,但是日期数据类型具有特殊关联的属性。为每个日期值,Oracle 存储以下信息: 世纪、 年、 月、 日期、 小时、 分钟和秒。日期时间数据类型的值为公元前4712年1月1日到公元9999年12月31日.Oracle中的SYSDATE函数的功能是返回当前日期和时间.
如 : 从伪表中查询当前系统时间:
select sysdate from dual;
存储在数据库里的时间格式是:yyyy-MM-dd hh24:mi:ss
,但是查询出来的却是dd-MM-yy hh24:mi:ss
,可以通过调用函数解决问题,代码如下:
select to_char(sysdate,'yyyy-MM-dd HH:mm:ss') from dual;
TIMESTAMP类型用户存储日期的年,月,日,以及时间的小时,分和秒,其中秒值精确到小数点后6位,该数据类型同时包含时区信息,SYSTIMESTAMP函数功能是返回当前日期,时间和时区.
如 : 从伪表中查询当前系统时间以及时区
select systimestamp from dual;
界面显示:
02-9月 -17 05.58.20.389000 下午 +08:00
标注:+08:00 意思是:GMT(Greenwich Mean Time)是格林尼治标准时间,+08:00 指标准时间加8小时,也就是北京时间.
内置的LOB数据类型包括BLOB、CLOB、NCLOB、BFILE(外部存储)的大型化和非结构化数据,如文本、图像、视频、空间数据存储。BLOB、CLOB、NCLOB类型
它存储单字节和多字节字符数据。支持固定宽度和可变宽度的字符集。CLOB对象可以存储最多4GB((4 gigabytes-1) * (database block size)) 大小的字符
它存储UNICODE类型的数据,支持固定宽度和可变宽度的字符集,NCLOB对象可以存储最多4GB((4 gigabytes-1) * (database block size))大小的文本数据。
它存储非结构化的二进制数据大对象,它可以被认为是没有字符集语义的比特流,一般是图像、声音、视频等文件。BLOB对象最多存储4GB((4 gigabytes-1) * (database block size))的二进制数据。
用于为操作系统文件提供只读访问。在数据库之外进行维护,不是数据库的一部分。
该表主要目的是为了保证在使用SELECT语句中的语句的完整性而提供的。
一般用于验证函数。例如:
select sysdate,to_char(sysdate,'yyyy-mm-dd HH24:mm:ss') from dual;
10字节.代表记录的地址。显示为18位的字符串。用于定位数据库中一条记录的一个相对唯一地址值。通常情况下,该值在该行数据插入到数据库表时即被确定且唯一。ROWID它是一个伪列,它并不实际存在于表中.
例如:查询emp表中的伪列:
SQL> select rowid,ename from emp where ename='SMITH';
输出结果:
ROWID ENAME
------------------ ------------
AAAR3sAAEAAAACXAAA SMITH
其中这里的AAAR3s是数据库对象编号,AAE是文件标号,AAAACX是块编号,最后三位AAA是行编号。
ROWNUM是一个序列,会根据sql语句自动给你加上一列排好顺序的序号列。
例如:
select rownum, ename,empno from emp where rownum <=5;
结果正常输出.
ROWNUM ENAME EMPNO
------- -------------------- ----------
1 SMITH 7369
2 ALLEN 7499
3 WARD 7521
4 JONES 7566
5 MARTIN 7654
rownum是动态的,必有查询结果,然后再给查询的结果集添加上这个列。 例如:第一条记录的rownum是1 ,第二条是2,以此类推。
若是查询 rownum > 5 以后的员工,比如:
select rownum, ename,empno from emp where rownum >5; -- 查询结果为空集
当产生结果集时,oracle会产生一条rownum为1的记录,显然不符合条件;那么就会产生第二条记录,同样rownum=1,也不符合记录; 一直下去,导致最后上述sql产生的结果集时空集。
如果需要查询到结果,需要使用子查询:
select rownum,t.rn,ename,empno
from (select rownum rn, e.* from emp e where rownum < 10) t
where t.rn > 5;
--注意: 1.rownum只能用< 或者<= 2. <或者<=需要放在子查询里面
Oracle数据库查询的分页就是通过 rownum 进行的:
–分页步骤(比如每页显示2条,查询第2页)
–第一步,限定条件是rownum小于结束行,结果列把rownum作为结果集
select rownum rn, e.* from emp e where rownum < 5;
–第二步以第一步的结果集作为一张表,限定条件是第二步的rownum列大于开始行号,结果是:
select *
from
(select rownum rn, e.* from emp e where rownum < 5) b
where b.rn > 2;
-- 5代表 endNum
-- 2代表 startNum
-- pageNo 2
-- pageSize 2
关于pageNo 与 pageSize 公式总结如下
pageNo:当前的页码
pageSize:每页的记录数
pageNo pageSize startNum endNum
1 2 0 3
2 2 2 5
3 2 4 7
-- startnum endNum pageNo pagesize
-- 0=(1-1)*5 6 =5*1+1 1 5
-- 5=(2-1)*5 11=5*2+1 2 5
-- 10 16 3 5
-- startnum=(pageNo-1)*pageSize
-- endNum = (pageNo * pageSize) + 1
已知pageNo和pageSize数计算startNum和endNum的公式
startNum = (pageNo - 1) * pageSize
endNum = (pageNo * pageSize) + 1
分页代码如下:
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM < endNum
)
WHERE RN > startNum
也可以在查询的最外层控制分页的最小值和最大值。查询语句如下
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
)
WHERE RN BETWEEN startNum+1 AND endNum+1
返回顶部
SQL(Structured Query Language) 是结构化查询语言的缩写。
SQL是在关系数据库上执行数据操作、检索及维护所使用的标准语言,可以用来查询数据,操纵数据,定义数据,控制数据,所有数据库都使用相同或者相似的语言。
SQL可分为:
1) 数据定义语言(DDL:Data Definition Language) : CREATE(创建),ALTER(更改),TRUNCATE(截断),DROP(删除) 等命令
2) 数据操纵语言(DML:Data Manipulation Language) : INSERT(插入),SELECT(选择),DELETE(删除)和UPDATE(更新)等命令
3) 事务控制语言(TCL:Transaction Control Language) : COMMIT(提交),SAVEPOINT(保存点),ROLLBACK(回滚)等命令
4) 数据查询语言(DQL:Data Query Language) : SELECT(查询)等命令
5) 数据控制语言(DCL:Data Control Language) : GRANT(授予),REVOKE(回收)等命令
执行SQL语句时,用户只需要知道其逻辑含义,而不需要知道SQL语句的具体执行步骤
数据定义语言用于改变数据库结构,包括创建、更改和删除数据库对象
用于操纵表结构的数据定义语言命令有:
创建表的语法如下:
语法
CREATE TABLE [schema.] table_name (
column datatype [default ‘输入默认值’ ] [null/not null],
column datatype…);
在语法中:
创建表的时候,需要制定唯一的表名称,表内唯一的列名称,列的数据类型及其宽度
示例如下:
创建一个stuInfo
表,用来存储学员的个人信息,如姓名,学号和年龄等.
代码如下:
CREATE TABLE stuInfo /*-创建学员信息表-*/
(
stuNo CHAR(6) NOT NULL, --学号,非空必填
stuName VARCHAR2(20) NOT NULL, --学员姓名,非空(必填)
stuAge NUMBER(3,0) NOT NULL, --年龄,非空(必填)
stuID NUMBER(18,0),--身份证号,代表18位数字,小数位数为0
stuSeat NUMBER(2,0) --座位号
)
-- 备注:/* */中的内容为多行注释
-- 后面的内容为单行注释
1.添加字段:
alter table 表名 add (字段 字段类型) ;
2.修改字段类型:
alter table 表名 modiy (字段 字段类型 [default ‘输入默认值’ ] [null/not null] ); 修改多个字段用逗号隔开
3.删除字段:
alter table 表名 drop (字段);
示例1 : 更改stuName列的定义,使此列能容纳25个字符,语句如下
ALTER TABLE stuInfo MODIFY (stuName VARCHAR2 (25));
示例2 : 向stuInfo 表添加stuTel_no( varchar2(12) ) 和stuAddress( varchar2(20) ) 两个列
ALTER TABLE stuInfo ADD (stuTel_no VARCHAR2(12),stuAddress VARCHAR2(20));
示例3 : 从stuInfo表中删除列
ALTER TABLE stuInfo DROP COLUMN stuTel_no; --删除stuTel_no列
--或者
ALTER TABLE stuInfo DROP (stuAddress); --删除stuAddress列
示例4 : 删除表stuInfo
DROP TABLE stuInfo;
Truncate table 表名 删除表中的数据
删除表 DROP TABLE
Truncate 与 Delete的区别在于:
Truncate命令快速删除记录并释放空间, 不使用事务处理,因此无法回滚。
Delete命令可以在执行删除之后,通过Rollback撤销删除。如果确定表中的数据不再使用,使用Truncate命令效率更高。
数据操纵语言用于检索、插入和修改数据
INSERT INTO 表名 VALUES(‘值’, ‘值’);此致的值必须与表中所有字段一一对应
INSERT INTO 表名(字段,字段) VALUES(‘值’, ‘值’);此致的值与字段一一对应
示例:插入stuInfo表数据
INSERT INTO stuInfo VALUES (1,'张三',18,null,1);
INSERT INTO stuInfo VALUES (2,'李四',20,null,2);
INSERT INTO stuInfo VALUES (3,'王五',15,null,3);
INSERT INTO stuInfo VALUES (4,'张三',18,null,4);
INSERT INTO stuInfo VALUES (5,'张三',20,null,5);
commit; -- 若想数据长久保存别忘了写commit
UPDATE 表名 SET 字段= ‘值’ WHERE 字段= ‘值’;
DELETE FROM 表名;
DELETE FROM 表名 WHERE 字段名=‘字段值’;
1) 选择无重复的行
要防止选择重复的行,可以在SELECT命令中包含DISTINCT字句:
SELECT DISTINCT stuName,stuAge FROM stuInfo;
输出结果:
STUNAME STUAGE
-------------------------------------
王五 15
张三 18
李四 20
张三 20
注意: DISTINCT 字句筛选结果集中内容相同的行,仅保留一行
2) 带条件和排序的SELECT 命令
查询 年龄>17岁,按照姓名升序,如果姓名相同按照年龄降序排序的结果集
SELECT stuNo,stuName, stuAge
FROM stuInfo
WHERE stuAge>17
ORDER BY stuName ASC, stuAge DESC;
3) 使用列别名
列别名为是列表达式提供的另一个名称,位于列表表达式后面,并显示在列标题中.列别名不会影响列的实际名称
使用列别名显示姓名,年龄
select stuName as 姓名,stuAge 年龄 from stuInfo;
如果列别名中指定含有特殊字符(如空格)的列标题,则使用双引号括起来.
4) 利用现有的表创建新表
Oracle 允许利用现有的表创建新表,完成此操作的语法如下:
语法:
CREATE TABLE
as SELECT {*| column(s)} FROM
[WHERE
];
此命令可以把现有表中的所有记录复制到新表中,也可以仅复制选定的列或者只复制结构而不复制表记录
复制表stuInfo并完全复制表中所有记录到新表newStuInfo1:
CREATE TABLE newStuInfo1 AS SELECT * FROM StuInfo;
复制表stuInfo并完全复制表中部分记录到新表newStuInfo2:
CREATE TABLE newStuInfo2 AS SELECT stuName,stuNo,stuAge FROM StuInfo;
只复制表stuInfo结构到新表newStuInfo2:
CREATE TABLE newStuInfo2 AS SELECT * FROM StuInfo where 1=2;
1) 查看表中行数
执行SQL语句:
SELECT COUNT(*) FROM stuInfo;
2) 取出stuName,stuAge 列不存在重复数据的记录
SELECT stuName,stuAge
FROM stuInfo
GROUP BY stuName,stuAge
HAVING COUNT(stuName||stuAge) < 2;
3) 删除stuName,stuAge重复的行:
可分步实现:
-- 1 . 查找重复的记录 只保留第一条
SELECT MAX(ROWID) FROM stuInfo
GROUP BY stuName,stuAge HAVING COUNT(*)>1;
-- 2 . 查找不重复的记录
SELECT MAX(ROWID) FROM stuInfo
GROUP BY stuName,stuAge HAVING COUNT(*)=1;
-- 3 . 合并结果集,获得所有符合条件且不重复的记录
SELECT MAX(ROWID) FROM stuInfo
GROUP BY stuName,stuAge HAVING COUNT(*)>1
UNION
SELECT MAX(ROWID) FROM stuInfo
GROUP BY stuName,stuAge HAVING COUNT(*)=1;
-- 4 . 获得所有重复记录的ROWID
DELETE
FROM stuInfo
WHERE ROWID NOT IN(
SELECT MAX(ROWID)
FROM stuInfo
GROUP BY stuName,stuAge
HAVING COUNT(*)>1
UNION
SELECT max(ROWID)
FROM Stuinfo
GROUP BY stuName,stuAge
HAVING COUNT(*)=1
);
4) 查看当前用户所有的数据量>10万的表信息
/*
===========================================================
| 查看当前用户所有数据量>100万的表的信息
============================================================
*/
SELECT *
FROM user_all_tables a
WHERE a.num_rows>1000000;
在Oracle数据库中事务控制语句(TCL) 主要由以下部分组成:
(1) COMMIT : 提交事务,即把事务中对数据库的修改进行永久保存
(2) ROLLBACK : 回滚事务,即取消对数据库所做的任何修改.
(3) SAVEPOINT : 在事务中创建存储点.
(4) ROLLBACK TO
: 将事务回滚到存储点.
需求说明:
事务控制语句应用举例,创建部门表(dept
),插入部门记录.关键代码如下:
--执行步骤一:创建dept 表
CREATE TABLE DEPT
( DEPTNO NUMBER(2) PRIMARY KEY, --部门编号
DNAME VARCHAR2(14) , --部门名称
LOC VARCHAR2(13) --地址
) ;
--执行步骤二:插入数据
INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON');
COMMIT;
--执行步骤三:操作dept 表
INSERT INTO dept VALUES(50,'a',null);
INSERT INTO dept VALUES(60,'b',null);
SAVEPOINT a; --创建事务存储点
INSERT INTO dept VALUES(70,'c',null);
SELECT * FROM dept --查看有70号部门 ;
ROLLBACK TO SAVEPOINT a --将事务回滚到存储点a ;
SELECT * FROM dept --查看有已经没有了70号部门 ;
--执行步骤四:查看dept 表,有50、60 号部门
SELECT * FROM dept;
--执行步骤五:回滚
ROLLBACK;
--执行步骤六:查看dept 表
SELECT * FROM dept --已经没有了50、60 号部门;
(1) 回滚到保存到"a"
, 表示保存点以后所有的数据操作都取消,故只插入了两个部门;
(2) 事务没有结束,必须再执行COMMIT
或者ROLLBACK
命令来结束事务.
执行了3个INSERT语句,如果要提交,只能提交所有的SQL语句,不能部分提交;如果要回滚,可以利用"事务保存点"
来做局部回滚,此时事务并没有结束.
数据控制语言,用来定义访问权限和安全级别。
GRANT <权限列表> to
; 例如:
-- 授予管理员角色权限(dba)授予scott用户 grant dba to scott;
REVOKE <权限列表> from
例如:
-- 将用户scott的管理员角色(dba)的权限收回 revoke dba from scott;
Oracle 的权限列表
CONNECT : 需要连接数据库的用户,特别是那些不需要创建表的用户,通常授予该权限
RESOURCE : 更为可靠和正式的数据库用户可以授予该角色,可以创建表,触发器,过程的
UNLIMITED TABLESPACE : 可以在其他表空间里随意建表。一般DBA要把这个 UNLIMITED TABLESPACE权限关掉
DBA : 数据库管理员角色权限,拥有管理数据库的最高权限.一个具有DBA角色的用户可以撤销任何其他用户甚至其他DBA权限.
Oracle中的权限与角色比较多,第二章会详细介绍.
查询语句中要执行基于数值的计算,可以在SQL命令中使用算术表达式.算术表达式由NUMBER数据类型的列名,数值常量和连接它们的算术操作符组成.*算术操作符包括 +(加) -(减) (乘) /(除)
比较操作符用于比较两个表达式的值.比较操作符包括**= , != , < , > , <= , >= , BETWEEN … AND…(检查是否在两个值之间) , IN(与列表中值相匹配) , LIKE(匹配字符模式) 和 IS NULL(检查是否为空) .**
逻辑操作符用户组合多个比较运算结果以生成一个或真或假的结果. 逻辑操作符包括 AND(与) , OR(或) 和 NOT(非).
示例代码如下:
/*
===========================================================
| 补充 :创建退休员工表
============================================================
*/
CREATE TABLE retireEmp AS SELECT * FROM emp;
-- 修改退休表中的列 empno 为 rempno
ALTER TABLE retireEmp RENAME COLUMN empno TO rempno;
-- 修改表中7788 编号的员工为 8888
UPDATE retireEmp SET rempno=8888 WHERE rempno=7782;
COMMIT;
示例1:union操作符
SELECT empno FROM emp
UNION
SELECT rempno FROM retireEmp;
示例2:union all 操作符
SELECT empno FROM emp
UNION ALL
SELECT rempno FROM retireEmp;
示例3:INTERSECT操作符
SELECT empno FROM emp
INTERSECT
SELECT rempno FROM retireEmp;
示例3:MINUS操作符
SELECT empno FROM emp
MINUS
SELECT rempno FROM retireEmp;
连接操作符(||) 用于将两个或多个字符串合并成一个字符串,或者将一个字符串与一个数值合并在一起.
示例:
输出岗位和员工姓名组合在一起的信息,格式"job_ename"
,如 "CLERK_SMITH"
,代码如下:
select job||'_'||ename from emp;
返回顶部
Oracle SQL 提供了用于执行特定操作的专用函数. Oracle将函数大致划分为单行函数,聚合函数和分析函数.单行函数可以大致划分为字符函数,日期函数,数字函数,转换函数以及其他函数.具体可查看手册.聚合函数也称为分组函数,是基于数据库表的多行进行运算,返回一个结果.
分析函数是对一个查询结果中的每个分钟进行运算,但每个分组对应的结果可以有多个.
将值从一种数据类型转换为另一种数据类型.常用的转换函数有以下几种:
此函数的语法为
TO_CHAR( d | n [, fmt] ),
其中,d是日期,n是数字,fmt是指日期或数字的格式.
TO_CHAR转换函数是将日期以fmt指定的格式转换为VARCHAR2数据类型的值.
示例如下:
SELECT TO_CHAR(sysdate,'YYYY"年"fmMM"月"fmDD"日" HH24:MI:SS') FROM dual;
-- 注意 使用 fm 格式来避免空格填充和数字零填充.
TO_CHAR函数也可以用来格式化数值,示例如下:将数值转换为字符串,并使用当前货币符号作为前缀,代码如下.
SELECT TO_CHAR (1210.7,'$9,999.00') from dual;
-- 备注:
-- 0表示:如果参数(double或者float类型)存在数字就显示数字,不存在数字就显示0
-- 9表示:如果参数(double或者float类型)存在数字就显示数字,不存在数字就显示空格
TO_DATE的功能是将字符串按照定制格式转换为日期类型,语法格式是:
TO_DATE(char[, fmt[, nlsparams]])
其中:char是要转换的字符串,fmt是转换格式,nlsparams是指定日期语言。
示例:将字符串"2013-07-13"
转换为日期格式,代码如下:
SELECT TO_DATE('2013-07-13','yyyy-MM-dd') FROM dual;
查看自己活了多少天:
SELECT ROUND((SYSDATE-TO_DATE('1992-04-22','YYYY-MM-DD')),0) FROM DUAL;
TO_NUMBER
函数将包含数字的字符串转换为NUMBER数据类型,从而可以对该数据类型执行算术运算.通常不必这样做,因为Oracle
可以对数字字符串进行隐式转换.
示例如下:
SELECT SQRT(TO_NUMBER('100')) FROM dual;
除了字符函数,日期函数,数字函数,转换函数外,还有其他一些单行函数,在此统称为其他函数.
将NULL转变为非NULL值。如果expr1为NULL,则取值expr2, expr2是非空值。
其中expr1和expr2可以是任何数据类型,但两个参数的数据类型必须是一致的。计算员工月收入,如果comm列为空值的话,最终计算结果将是空,不符合逻辑,所以先将取NULL值的comm列转换为0,再相加。
例如:查询员工姓名,工资,奖金,工资加+奖金(如果奖金为null,则奖金为0):
SELECT ename, sal, comm,sal + nvl(comm, 0) salary FROM emp;
和NVL函数功能类似,都是将NULL转变为非空值。
NVL2用来判断expr1是否为NULL,如果不是NULL,返回expr2,如果是NULL,返回expr3。
上述查询语句也可以使用NVL2函数,代码如下:
SELECT ename, sal, comm, nvl2(comm, sal + comm, sal) salary FROM emp;
如果value的值为if1,则返回then1的值;如果value的值为if2,则返回then2的值,…否则返回else的值.
如查看员工的入职月份:
select decode(to_char(hiredate,'MM'),'01','一月','02','二月','03','三月','04','四月','05','五月','06','六月','下半年') from emp;
Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是
对于每个组返回多行,而聚合函数对于每个组只返回一行。
分析函数的语法如下:
语法:
函数名([参数]) OVER ([分区子句(PARTITION BY)] [排序子句(ORDER BY)])
在语法中:
PARTITION BY
) : 表示将查询结果分为不同的组,功能类似于GROUP BY
语句,是分析函数工作的基础.默认会将所有结果作为一个分组.ORDER BY
) : 表示将每个分区进行排序.对于Oracle分析函数,本文只介绍 RANK,DENSE_RANK,ROW_NUMBER
的使用示例,以对分析函数进行初步了解.
RANK,DENSE_RANK,ROW_NUMBER
函数用于为每一条记录产生一个从1开始至N的自然数.N的值可能小于等于记录的总数.这三个函数的唯一区别在于遇到相同数据的排名时排名策略.3个函数用于解决累计排名问题.
几个排名函数的语法和用法:
示例演示:按照每个部门分组,对薪水从大到小排序,每个部门序号从1开始,同一个部门相同的薪水序号相同,且和下一条不同的记录之间空出排名序号.使用RANK分析函数解决,代码如下:
SELECT ename,deptno, sal,
RANK() OVER(PARTITION BY deptno ORDER BY sal DESC) RANK
FROM emp;
结果如下:
ENAME DEPTNO SAL RANK
-------------------- ---------- ---------- ----------
KING 10 5000 1
CLARK 10 2450 2
MILLER 10 1300 3
SCOTT 20 3000 1
FORD 20 3000 1
JONES 20 2975 3
ADAMS 20 1100 4
SMITH 20 800 5
BLAKE 30 2850 1
ALLEN 30 1600 2
TURNER 30 1500 3
MARTIN 30 1250 4
WARD 30 1250 4
JAMES 30 950 6
示例演示:按照每个部门分组,对薪水从大到小排序,每个部门序号从1开始,同一个部门相同的薪水序号递增,顺序排名.使用ROW_NUMBER分析函数解决,代码如下:
SELECT ename,deptno, sal,
ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY sal DESC) ROW_NUMBER
FROM emp;
结果如下:
ENAME DEPTNO SAL ROW_NUMBER
---------- ---------- ---------- ----------
KING 10 5000 1
CLARK 10 2450 2
MILLER 10 1300 3
SCOTT 20 3000 1
FORD 20 3000 2
JONES 20 2975 3
ADAMS 20 1100 4
BLAKE 30 2850 1
ALLEN 30 1600 2
TURNER 30 1500 3
WARD 30 1250 4
MARTIN 30 1250 5
JAMES 30 950 6
SMITH 40 800 1
示例演示:按照每个部门分组,对薪水从大到小排序,每个部门序号从1开始,同一个部门相同的薪水序号相同,且和下一条不同记录之间 不
空出排名.使用DENSE_RANK分析函数解决,代码如下:
SELECT ename,deptno, sal,
DENSE_RANK() OVER(PARTITION BY deptno ORDER BY sal DESC) DENSE_RANK
FROM emp;
结果如下:
ENAME DEPTNO SAL DENSE_RANK
---------- ---------- ---------- ----------
KING 10 5000 1
CLARK 10 2450 2
MILLER 10 1300 3
SCOTT 20 3000 1
FORD 20 3000 1
JONES 20 2975 2
ADAMS 20 1100 3
BLAKE 30 2850 1
ALLEN 30 1600 2
TURNER 30 1500 3
WARD 30 1250 4
MARTIN 30 1250 4
JAMES 30 950 5
SMITH 40 800 1
https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html
对应Oracle的版本下载对应的Oracle的客户端,例如:Oracle 11g 可以下载 [instantclient-basic-win-x86-64-11.1.0.7.0.zip]
:https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html#license-lightbox)
解压之后的文件夹叫:instantclient_11_1.可以放在本地磁盘任意目录下.例如:D:\app\instantclient_11_1
D:\app\instantclient_11_1
)目录下新建文件tnsnames.ora
,或者将Oracle安装目录\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora
复制到该目录下 ,打开写入如下内容:ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.100)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCL)
)
)
ORCL
是远程数据库在本地的主机名,192.168.0.100是远程服务器的IP地址,ORCL是远程数据库的名称。win+r 打开运行窗口 , 输入命令:sysdm.cpl
, 打开系统属性 , 点击高级找到环境变量
点击环境变量 , 新建一个环境变量,名为TNS_ADMIN,值为tnsnames.ora文件所在路径。
TNS_ADMIN
变量值 : D:\app\instantclient_11_1
# Oracle Home
D:\app\instantclient_11_1
# scott tiger
# OCI library
D:\app\instantclient_11_1\oci.dll
配置完成后关闭PL/SQL ,再重启.
主机名就会出现在PL/SQL Developer的列表里,输入用户名密码,就可以登录远程oracle 数据库。
若发现oci.dll
文件报错,则是客户端版本与服务器版本冲突,重新下载对应的客户端版本
当我们连接成功后有时候查询出来的数据会出现乱码的问题,这是因为本地的编码和服务器端编码不一致,这时候我们可以通过SQL语句:
select userenv('language') from dual;
查询出服务器端的编码,结果如下:
USERENV('LANGUAGE')
AMERICAN_AMERICA.ZHS16GBK
我们就需要添加一个环境变量NLS_LANG
,值为: AMERICAN_AMERICA.ZHS16GBK
,然后重启PL/SQL就不会再有乱码问题了
保存网络配置,重启oracle的数据库服务 以及 监听服务
-- 查看插接式数据库
show pdbs;
-- 查看参数 FILE_NAME_CONVERT
select name from v$datafile;
-- 创建 插接式数据库
create pluggable database orclpdb
admin user orclpdb identified by orcl
file_name_convert=('D:\APP\ADMINISTRATOR\ORADATA\ORCL\PDBSEED\',
'D:\APP\ADMINISTRATOR\ORADATA\ORCL\ORCLPDB\');
-- 打开单个pdb数据库
alter pluggable database orclpdb open;
-- 关闭pdb数据库
alter pluggable database orclpdb close immediate;
-- 切换到pdb数据库中
alter session set container=ORCLPDB;
-- 创建scott用户
creat user scott identified by tiger;
-- 授予dba权限
grant dba to scott;
-- 执行sql脚本文件
@D:\app\Administrator\product\12.2.0\dbhome_1\rdbms\admin\scott.sql;
-- 查看某用户下有哪些表名
select table_name from all_tables a where a.OWNER = upper('scott');
-- 保存开启状态
ALTER PLUGGABLE DATABASE orclpdb SAVE STATE;
drop pluggable database orclpdb including datafiles;