Oracle安装
下载链接
提取码:ac8c
口令管理
数据库创建完毕后,在默认的用户中,SYS和SYSTEM用户没有锁定,安装成功后可以直接使用,SCOTT用户默认是锁定的,需要把SCOTT用户解锁才能正常使用。
SQL*Plus命令行工具
描述
该命令行工具,提供了与数据库交互的能力和维护数据库的能力,包括了Oracle自带的SQL*Plus工具的全部功能,在Oracle管理中经常使用。
- 启动该工具:在命令输入 sqlplus/nolog
- 与Oracle服务器连接:conn 用户名/密码 as 连接身份@服务器连接字符串
例如:conn scott/scott@localhost:1521/orcl
Oracle连接身份
“sysdba” 即数据库管理员,权限有:打开数据库服务器;关闭数据库服务器;备份数据库;恢复数据库;日志归档;会话限制;管理功能;创建数据库;
“sysyoper”即数据库操作员,权限包括:打开数据库服务器;关闭数据库服务器;备份数据库;恢复数据库;日志归档;会话限制;
“normal”即普通用户,权限只有查询某些数据表的数据;
SYS和SYSTEM 是每个ORACLE 数据库系统缺省安装的两个帐户。
- SYS 是所有内部数据库表、结构、过程包、等拥有者,此外它还拥有 V$ 和数据字典视图,并创建所有封装的数据库角色(DBA,CONNECT,RESOURCE)。Sys是一个唯一能访问特定内部数据字典的用户。
- System 也是在安装ORACLE 时创建的用户,用于 DBA 任务的管理。
使用出错记录
- ORA-12560TNS:协议适配器错误
原因:服务没开处理办法:需启动OracleOraDb11g_home1TNSlistener和启动OracleServiceORCL两个服务。 - ORA-01017: invalid username/password; logon denied
原因:密码输入不正确
用户名:system 密码:manager
用户名:sys 密码:change_on_install
处理办法:密码口令输入方式 :密码 as sysdba
Oracle用户和权限
创建用户语法:create user 用户名 identified by 口令 account lock|unlock;
例如:创建一个用户tom,密码是tompassword(密码不能使用数字开头,因为oracle需要转成大写),默认非锁定。
语句为:create user tom identified by tompassword account unlock;
创建好用户,还需要把权限和角色授予用户,一般情况下,一个普通用户scott,拥有connect和resource两个角色即可进行常规的数据库开发工作。系统权限只能由DBA用户授权,对象授权由拥有该对象的用户授权。
授权语法:grant 角色|权限 to 用户(角色)
例如:给tom用户授权connect和resource
语句:
grant connect to tom;
grant resource to tom;
回收权限语法:revoke 角色|权限 from 用户(角色)
修改用户的密码语法:alter user 用户名 identified by 新密码
修改用户处于锁定(非锁定)状态:alter user 用户名 account lock|unlock;
数据操作与查询
SQL命令组成
- 数据定义语言(DDL):包括create(创建)、alter(修改)和drop命令等
- 数据操纵语言(DML):包括insert(插入)、updata(更新)、delete(删除)和select… for updata(查询)等。
- 事务控制语言(TCL):包括commit(提交)命令、savepoint(保存点)命令、rollback(回滚)命令。
- 数据查询语言(DQL):包括基本查询语句、Order By 子句、Group By 子句等。
- 数据控制语言(DCL),grant(授权)命令、revoke(撤销)命令。
数据定义语言(DDL)
数据库操作:
1 | -- 日期类型 |
数据操纵语言(DML)
插入数据的语法为:
INSERT INTO 表名(列名1,列名2……) VALUES (值1,值2……)
查询数据的语法是:
SELECT * |列名|表达式 FROM 表名 WHERE 条件 ORDER BY 列名
更新数据的语法是:
UPDATE 表名 SET 列名1=值,列名2=值…… WHERE 条件
删除数据的语法是:
DELETE FROM 表名 WHERE 条件
删除表中所有数据语法:
TRUNCATE TABLE 表名
truncate 和delete都能把表中的数据全部删除,他们的区别是:
- truncate是DDL命令,删除的数据不能恢复;DELETE 命令是DML 命令,删除后的数据可以通过日志文件恢复。
- 如果一个表中数据记录很多,truncate相对delete速度快。
由于truncate命令比较危险,因此在实际开发中,truncate命令慎用。
一般而言,drop > truncate > delete
- truncate只能对table,delete可以是table和view
- truncate 和delete只删除数据,drop则删除整个表(结构和数据)。
数据库操作:
1 | --插入语句 |
高级查询
1 | --消除重复行查询 |
Oracle中的伪列
伪列就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。
伪列ROWID和ROWNUM区别:
ROWNUM 与ROWID 不同,ROWID 是插入记录时生成,ROWNUM 是查询数据
时生成。ROWID 标识的是行的物理地址。ROWNUM 标识的是查询结果中的行
的次序。
1 | -- Oracle 中的伪列 |
序列(Sequence)
什么是序列
场景 :需要生成一个 唯一、递增、不重复的数字 ,通常用作主键的值。
Sequence(序列)是oracle用来生成连续的整数数据的对象。由于oracle中没有设置自增列的方法,所以在oracle数据库中主要用序列来实现主键自增的功能。
创建序列的语法
CREATE SEQUENCE sequence //创建序列名称
[INCREMENT BY n] //递增的序列值是 n 如果 n 是正数就递增,如果是负数就递减 默认是 1
[START WITH n] //开始的值,递增默认是 minvalue 递减是 maxvalue
[{MAXVALUE n | NOMAXVALUE}] //最大值
[{MINVALUE n | NOMINVALUE}] //最小值
[{CYCLE | NOCYCLE}] //循环/不循环
[{CACHE n | NOCACHE}];//分配并存入到内存中
数据库操作:
1 | --创建序列 |
触发器(Trigger)
场景 :在某个事件(如 INSERT、UPDATE、DELETE)发生前或发生后,自动执行一段 PL/SQL 逻辑。
其他典型场景 :
- 审计日志 :记录某张表的修改历史(
AFTER UPDATE时插入旧值到日志表)。 - 数据校验 :
BEFORE INSERT检查某些字段合法性,不合法则抛出异常。 - 同步更新 :例如更新主表时自动更新冗余表或汇总表。
- 禁止操作 :在某些条件下阻止删除或更新。
注意 :触发器虽然方便,但滥用会增加复杂度和隐式逻辑,影响性能,建议只在必要场景使用。
数据库主键生成方式对比:自增数字 vs sys_guid()
在银行、金融等业务系统中,主键(Primary Key)的设计至关重要。主键不仅需要保证唯一性,还可能影响排序、查询性能、数据迁移等。常见的主键生成方式有两种:
- 序列 + 触发器(自增数字)
sys_guid()/ UUID(全局唯一标识)
两种方式对比
| 特性 | 序列 + 触发器 | sys_guid() / UUID |
|---|---|---|
| 值类型 | 数字(NUMBER) | 32位十六进制字符串(VARCHAR2(32)) |
| 唯一性范围 | 数据库实例内唯一 | 全局唯一(跨数据库、跨主机) |
| 是否有序 | ✅ 单调递增(可保证顺序) | ❌ 随机、无序 |
| 可读性 | 高(1,2,3…) | 低(2BA6C3F4...) |
| 存储空间 | 小(NUMBER(10) 约 7 字节) | 大(32 字节) |
| 索引性能 | 较好(B+树插入顺序) | 较差(随机插入可能导致索引分裂) |
| 是否需要额外对象 | 需要序列 + 触发器 | 只需默认值 default sys_guid() |
| 并发竞争 | 可能有锁争用(取 NEXTVAL) | 无竞争(各自生成) |
| 跨系统合并数据 | 易冲突(不同库都从 1 开始) | 无需处理,直接合并 |
建表脚本差异对比
使用序列 + 触发器(自增数字)
1 | -- 创建表,主键字段为数字类型 |
使用 sys_guid()(全局唯一)
1 | -- 创建表,主键字段为 VARCHAR2(32),默认值使用 sys_guid() |
无需序列,无需触发器,代码更简洁。
适用场景分析
什么时候使用序列 + 触发器(自增数字)
| 场景 | 说明 |
|---|---|
| 需要人工可读、顺序可追溯 | 例如流水号、工单号、批次号,业务人员希望看到连续增长的数字。 |
| 数据量巨大且需要按主键顺序扫描 | 自增主键在 B+ 树中顺序插入,索引维护代价低,范围查询性能好。 |
| 单库或数据不会跨实例合并 | 没有总分汇总需求,不怕主键冲突。 |
| 对存储空间敏感 | 数字主键占用空间小,索引也小,节省磁盘和内存。 |
什么时候使用 sys_guid()
| 场景 | 说明 |
|---|---|
| 分布式、总分结构 | 各网点(分行)独立插入数据,需要汇总到总行时主键不冲突。 |
| 高并发写入 | 避免序列成为锁瓶颈,sys_guid() 在应用层或数据库层无锁生成。 |
| 不希望暴露业务量 | 自增主键会泄露每天或每小时的插入量,sys_guid() 无法猜测。 |
| 简化开发 | 无需维护序列和触发器,只需 default sys_guid()。 |
典型案例分析
| 表名 | 主键方式 | 原因 |
|---|---|---|
IB_LOG_CFCAOPLOG_LOG(协议日志表) |
序列 + 触发器 | 日志量大,需要按序号归档、清理;不同库间不合并数据。 |
IB_AUX_FIELDQUESTIONS_INFO(答疑问题表) |
sys_guid() |
多网点可能各自生成问题记录,将来需要汇总到总行知识库,避免主键冲突。 |
正式库执行SQL示例
1 | --drop table IB_LOG_CFCAOPLOG_LOG; |
PL/SQL数据库工作日常笔记
查询有哪些关联流水的笔数超过 10 条
1 | SELECT SERIALNO, COUNT(*) AS TASK_COUNT |
字符串型任务号 MAX 取值错误案例
1 | --错误原SQL写法 |
执行顺序(从内到外)
| 步骤 | 表达式 | 作用 |
|---|---|---|
| 1 | substr(taskid, 28) |
从第 28 位开始截取(数字序号部分) |
| 2 | to_number(...) |
将序号转为数字 |
| 3 | max(...) |
取数字最大值 (10 > 9) |
| 4 | to_char(...) |
转回字符串('10') |
| 5 | substr(max(taskid), 0, 27) |
取任意一个 TASKID 的前 27 位 (固定前缀) |
| 6 | || |
连接前缀 + 最大序号 |
最终结果 :ABCS...2966 + 10 = ABCS...296610
问题现象
某业务系统使用 任务号(TASKID) 标识同一流水号下的不同子任务。任务号格式为:固定前缀 + 数字序号,例如:
ABCS0202604270000000162966010(序号 10)ABCS020260427000000016296609(序号 9)
出现的问题:
- 业务上序号 10 > 9,但 SQL 查询
MAX(TASKID)返回的是 9 - 导致生成新任务号时重复或越界
根本原因
MAX(TASKID) 按字符串字典序比较,而不是按数字大小比较
字符串比较规则:
从左到右逐字符比较,一旦分出大小就停止。
| 步骤 | ABCS...609 |
ABCS...610 |
比较结果 |
|---|---|---|---|
| 前缀比较 | 相同 | 相同 | 继续 |
| 序号第一位 | 6 |
6 |
相等 |
| 序号第二位 | 0 |
1 |
0 < 1 |
结论:...609 > ...610(字符串结果与数值相反)
创建视图表
注意:该柜员流水日志登记表由于核心、ESB等后台系统接口未规范请求返回报文配置,需使用临时视图表进行处理后,就可以点击报文格式化XML的功能了。
1 | --PL/SQL数据库管理工具不规范请求响应报文格式化处理方法 |
创建临时备份表
1 | --创建一张备份表:只复制结构,不复制数据 |
关联表查询
打印表关联查询
1 |
|
下拉框关联查询
1 | --下拉框信息表 |
查询当前被锁定的对象信息
1 | --查询表被谁锁住的语句 |
查询某个时间戳之前的数据
比如刚修改提交了影像补拍信息表中的某些数据,突然想还原修改之前的数据,可以通过以下SQL语句查询24小时内的内容:
1 | select * from IB_IMAGE_TIPS_INFO as of timestamp to_timestamp('2024-09-18 14:00:00','yyyy-mm-dd hh24:mi:ss') |
含义如下:
select * from IB_IMAGE_TIPS_INFO:选择所有来自表IB_IMAGE_TIPS_INFO的数据。as of timestamp:这个子句用于 Oracle 的闪回查询(Flashback Query),它允许查询过去某个时间点的数据。意思是要查询表在某个过去时间点的状态。to_timestamp('2024-09-18 14:00:00', 'yyyy-mm-dd hh24:mi:ss'):使用to_timestamp函数将字符串'2024-09-18 14:00:00'转换为时间戳类型,格式为yyyy-mm-dd hh24:mi:ss,表示要查询的历史数据的具体时间点为 2024 年 9 月 18 日 14:00:00。
&&运算符的插入
在插入SQL语句中有&&运算符却插入失效时,插入前先执行以下SQL语句:
1.set define off //关闭替代变量功能
2.执行要插入的SQL语句。
3.set define on //开启替代变量功能
decode函数
一 两种语法格式
1 decode(expression,value,result1,result2)
如果expression=value,则输出result1,否则输出result2
例子:
1 | select decode(1+2,3,'a','b') //(1+2=3,则输出a) |
2 decode(expression,value1,result1,value2,result2,value3,result3……,default)
如果expression=value1,则输出result1,expression=value2,输出reslut2,expression=value3,输出result3,
若expression不等于所列出的所有value,则输出为default
例子:
1 | select decode(score,100,'No.1',90,'No.2',80,'No.3','Other'),name from grade |
NVL函数
含义
nvl是用于判断某字段值是否为空然后作以相关处理的函数,类似于简易版的三元表达式。
分类
- 两个参数的nvl函数:nvl(str1,str2)
a. 含义:如果第一个参数不为空的话,则该表达式返回第一个参数的值,若第一个参数为空时,则返回第二个参数的值。
b. 应用场景:
- 可以设置字段如果为空的默认值。例如如果一个人在注册游戏时不填写用户名称时默认取你注册用的微信名称一样。
- 也可以用于外关联(join等)时两个表中有重复字段但是值不一样时,可以设置该字段取值的优先级别。例如两个事件表,一个是紧急事件表,另一个是基本事件表,两个表中都有一个字段名为事件紧急程度,这里我们就可以先将两个表进行关联,在设置事件紧急程度时首先取紧急事件表中该字段的内容,如果为空再取基本事件表中该字段的内容。
- 三个参数的nvl函数:nvl2(str1,str2,str3)
a. 含义:如果str1的值为空则返回str3,如果不为空则返回str2
b. 应用场景:可以使用与字符串的拼接,如果该字符串为空则直接返回前缀,若字符串不为空,则返回前缀拼接当前字符串之后再返回。
sign函数
含义:比较大小函数sign
sign(x)或者Sign(x)叫做符号函数,其功能是取某个数的符号(正或负):
当x>0,sign(x)=1;
当x=0,sign(x)=0;
当x<0, sign(x)=-1;
x可以是函数或计算表达式。
应用
NVL函数转换
1.多个条件查询时,考虑必输,非必输情况,非必输时考虑可能不输传空的转换。
解释:
- %s:表示输入条件的参数值,跟?占位符一样
- NVL(‘%s’,’’):表示第一个参数%s不为空的话,则返回第一个参数的值,若第一个参数为空时,则返回第二个参数的值,这时候赋空值,避免非必输项不输时也查不到记录的情况。
- decode(NVL(‘%s’,’’),’’,CONFIG_TYPE,’%s’):表示第一个参数与第二个参数相等都为空值时,输出CONFIG_TYPE,否则输出传入的%s值。
例子:
1 | select CONFIG_TYPE,CONFIG_NAME,PRAMETER_CODE,PARAMETER_NAME,CREATE_USER,STATUS,CREATE_DATE,CREATE_TIME,REMARK,REMARK1,REMARK2,REMARK3,SEQ_ID FROM ab_trade_config where CONFIG_TYPE=decode(NVL('%s',''),'',CONFIG_TYPE,'%s') and PRAMETER_CODE=decode(NVL('%s',''),'',PRAMETER_CODE,'%s') and |
使用sing函数分段
将成绩表中分数大于90分的分为优秀,80 ~90分为良好,70 ~80 分为中等, 60 ~70分为及格,60分以下为不及格。
1 | select name,decode(sign(score-90),1,'优秀',0,'优秀',-1,decode(sign(score-80),1,'良好',0,'良好',-1,decode(sign(score-70),1,'中等',0,'中等',-1,decode(sign(score-60),1,'及格',0,'及格',-1,'不及格')))) from grade |
解释:sign()函数的作用是,判断参数的值大于0则返回1,等于0则返回0,小于0则返回-1;
当socre大于或等于90时,socre-90>=0,sign()函数返回1或0,则输出‘优秀’,
在score-90<0的情况下,再判断socre-80,socre-80>=0,sign()函数返回1或0,则输出‘良好’,
以此类推,用decode()的嵌套配合sign()函数来实现对分数的分段以及相应的输出,
最后60分以下的就default为‘不及格’就可以了。
好的,以下是一份按操作顺序编排的 Oracle 数据库 DBA 用户管理笔记,专门针对开发环境中常见的用户创建、授权、密码延期、同义词配置等场景。每条 SQL 都附有清晰注释,你可以直接复制、按顺序执行。
DBA 用户管理
适用环境:开发库 / 个人测试库(非生产)
目标:快速创建新用户、授予合理权限、延长密码有效期、配置跨用户访问同义词
执行用户:拥有DBA或SYSTEM权限的账号(如ELEC、SYSTEM)
一、查看当前数据库用户及状态
1 | -- 1. 查看所有用户的基本信息(用户名、状态、密码过期时间) |
二、创建新用户并授予基本权限
1 | -- 1. 创建用户(用户名建议大写,Oracle 会自动转大写) |
三、授予 DBA 角色(仅开发环境,生产请勿滥用)
1 | -- 警告:DBA 角色权限极大,仅在个人开发库或受控测试环境中使用 |
四、处理密码过期问题(开发环境常用)
4.1 查看当前密码有效期策略
1 | -- 查看 DEFAULT Profile 的密码有效期 |
4.2 延长/取消密码有效期(推荐方式)
1 | -- 方法一:将 DEFAULT Profile 的密码有效期改为无限制(影响所有使用 DEFAULT Profile 的用户) |
4.3 让新 Profile 立即生效(重置密码为原密码)
1 | -- 如果用户当前密码即将过期,但不想改变密码内容,可以执行以下语句(等效于重置有效期) |
五、授予跨用户查询权限(访问其他用户的表)
5.1 授予系统级查询权限(强大但需谨慎)
1 | -- 允许用户查询任意表(包括其他 Schema 下的表) |
5.2 授予对象级权限(更安全,最小权限原则)
1 | -- 假设要允许 ELCC 查询 ELEC 用户下的 EMPLOYEES 表 |
六、创建同义词(免去加模式名前缀的麻烦)
6.1 创建单个私有同义词
1 | -- 语法:CREATE SYNONYM 目标用户.同义词名 FOR 源用户.表名; |
6.2 批量创建同义词(为源用户下的所有表生成同义词)
1 | -- 生成创建语句(结果复制后执行) |
6.3 查看已创建的同义词
1 | -- 查看当前用户(如 ELCC)拥有的私有同义词 |
七、常用维护操作(重置密码、解锁用户等)
1 | -- 1. 修改用户密码(立即生效) |
八、附录:PL/SQL 块中批量处理常见场景
场景一:为 ELCC 创建指向 ELEC 所有表的同义词(并输出成功/失败统计)
1 | SET SERVEROUTPUT ON; -- 仅在 SQL*Plus / 命令窗口需要,SQL 窗口不需要 |
场景二:将 ELEC 用户下所有表的 SELECT 权限授予 ELCC(更细粒度)
1 | DECLARE |


