Oracle中序列

1. Sequence 定义

在Oracle中可以用SEQUENCE生成自增字段。Sequence序列是Oracle中用于生成数字序列的对象,可以创建一个唯一的数字作为主键。

2. 为什么要用 Sequence

你可能有疑问为什么要使用序列?

不能使用一个存储主键的表并每次递增吗?或者将列设置为AUTO INCREMENT?

如果使用一个表来储存主键值的话,也许需要这样做:

  1. 创建一个新表来储存单一值。
  2. 每次插入新值到你想要插入的表时,在新表中使用该值。
  3. 然后更新新表(将其加1)。
  4. 这些逻辑都可以加入进存储过程。

然而这种方法存在以下几个问题:

  1. 如果你的事务中途失败,可能会得到重复的数据(插入的数据有一个ID,但新表没有增加)。这可以通过先递增然后插入来部分避免,但它仍然有中途失败的风险。
  2. 更新表将对其进行锁定,这可能会导致多个事务或用户出现问题。如果有一个用户,这可能是可以的,但如果程序有两个或多个用户,那么这可能会导致问题。
  3. 创建和维护一个表以及执行此操作的代码是繁重的工作。

Sequence是一个更好的方法,原因如下:

  1. 创建更简单。
  2. 使用起来更简单。
  3. 没有死锁以及导致其他事务出现问题的风险。

3. 创建(CREATE)Sequence

CREATE SEQUENCE [schema_name.]{sequence_name}    -- schema_name为将存储序列的模式名,sequence_name 为自定义名称;START WITH      n    -- n 为序列的初始值,默认为1;INCREMENT BY    n    -- n 为序列步长(序列增加的幅度),默认为1,如果是负则按此步长递减;[MINVALUE n | NOMINVALUE ]    -- 如果序列递减,定义序列生成器能产生的最小值,默认为1[MAXVALUE n | NOMAXVALUE ]    -- 定义序列生成器能产生的最大值,默认无限制(1e28 - 1)[CACHE n | NOCACHE]    -- value 是存放序列的内存块大小,默认20。对序列进行内存缓存可以改善序列性能。[ORDER | NOORDER]    -- 表示序列号是按照请求的顺序生成的。如果使用时间戳的序列号会有用。[CYCLE | NOCYCLE]    -- 值达到限制值后是否循环,如果不循环,达到限制值后,继续产生新值会发生错误 ;

使用缓存创建序列的缺点是,如果发生系统故障,所有未使用的缓存序列值都将“丢失”。这会在指定的序列值中产生“间隙”。当系统恢复时,Oracle将从序列中停止的位置缓存新数字,忽略所谓的“丢失”序列值。要恢复丢失的序列值,您可以始终执行ALTER sequence命令,将计数器重置为正确的值。

4. 使用 Sequence

CURRVALNEXTVAL可以在以下几个地方使用:

  • INSERT语句的VALUES子句。
  • SELECT语句的SELECT列表
  • UPDATE语句的UPDATE子句

它们不能在以下地方使用:

  • CHECK约束的条件
  • 视图查询
  • 实体化视图查询
  • 子查询
  • 带有DISTINCT关键字、GROUP BY子句或ORDER BY子句的SELECT语句
  • 使用UNION、INTERSECT或MINUS运算符与另一个SELECT语句组合的SELECT语句
  • SELECT语句的WHERE子句
  • CREATE TABLE或ALTER TABLE语句中列的DEFAULT值

最后一点意味着您不能使用DEFAULT关键字的序列将列设置为自动递增。有一种方法可以创建自动递增列,那就是使用触发器和序列。

1)基本Oracle序列示例

以下语句创建一个名为id_seq的升序Sequence,从10开始,递增10,最小值为10,最大值为100。由于CYCLE选项,序列一旦达到100就返回10。

CREATE SEQUENCE id_seqINCREMENT BY 10START WITH 10MINVALUE 10MAXVALUE 100CYCLECACHE 2;

使用NEXTVAL伪列获取序列的下一个值:

SELECT id_seq.NEXTVAL 
FROM dual;
以下是输出:NEXTVAL
----------10        


一旦通过NEXTVAL伪列获取序列号,就可以使用CURRVAL伪列重复访问它:

SELECT id_seq.CURRVAL 
FROM dual;
以下是输出:CURRVAL
----------10

注意!当调用NEXTVAL伪列时,它会为正在选择或插入的每一行数据返回一个新值。:

SELECT id_seq.NEXTVAL 
FROM dual;
以下是输出:NEXTVAL
----------20

但如果我使用几个NEXTVAL命令运行此查询的话:

SELECT id_seq.NEXTVAL AS nv1,
id_seq.NEXTVAL AS nv2,
id_seq.NEXTVAL AS nv3
FROM dual;
以下是输出:NV1         NV2         NV3
----------  ----------  ----------30          30          30

这表明NEXTVAL只为此记录调用过一次,并且每次的值都是相同的。

2) 在表列中使用 Sequence 的例子

在Oracle12c之前,只能在插入时将序列与表列间接关联

首先,创建一个名为tasks的新表:

CREATE TABLE tasks(id NUMBER PRIMARY KEY,title VARCHAR2(255) NOT NULL
);

其次,为tasks表的id列创建一个序列:

CREATE SEQUENCE task_id_seq;

第三,在任务表中插入数据:

INSERT INTO tasks(id, title)
VALUES(task_id_seq.NEXTVAL, 'Create Sequence in Oracle');INSERT INTO tasks(id, title)
VALUES(task_id_seq.NEXTVAL, 'Examine Sequence Values');

最后,从任务表中查询数据:

SELECT  id, title
FROMtasks;

在本例中,tasks表与task_id_seq序列没有直接关联。

3)通过标识列使用序列的例子

在Oracle12c中,您可以通过标识列将序列与表列相关联。

首先,用id列的identity列创建tasks表。

CREATE TABLE tasks(id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,title VARCHAR2(255) NOT NULL
);

Oracle创建了一个与 tasks表 的 id列 关联的序列。

由于Oracle自动为 id列 生成序列,因此在您的Oracle实例中,序列的名称可能不同。

Oracle创建序列-标识列

Oracle使用 sys.idnseq$ 来存储表和序列之间的链接。

此查询返回任务表和 ISEQ$$_74366序列 的关联:

SELECT a.name AS table_name,b.name AS sequence_name
FROM   sys.idnseq$ cJOIN obj$ a ON c.obj# = a.obj#JOIN obj$ b ON c.seqobj# = b.obj#
WHERE a.name = 'TASKS';  

第二,在任务表中插入一些行:

INSERT INTO tasks(title)
VALUES('Learn Oracle identity column in 12c');INSERT INTO tasks(title)
VALUES('Verify contents of the tasks table');

最后,从任务表中查询数据:

SELECTid, title
FROMtasks;

5. 删除(DROP)Sequence

要删除序列,它必须在您的模式中,或者您必须具有drop ANY sequence权限才能删除其他模式中的序列。

DROP SEQUENCE seq_name;

6. 更改(Alter)Sequence

创建序列后,可以更改序列的大多数特性。唯一不能更改的是序列的起始编号和序列的当前值。要更改的话需要删除并重新创建序列。

ALTER SEQUENCE seq02
INCREMENT BY 20
MAXVALUE 100000
CYCLE;

7. Sequence 原理

Oracle用Sequence来按需提供(几乎)无限的数字序列,这些序列保证是唯一的。最简单的方法就是保持一个全局可见的计数器,并在每次查询sequence_name.nextval的值时递增。

但Oracle必须跟踪提供的最后一个数字,以避免两次提供相同数字的风险——这对数据库系统来说很容易:只需将最新的数字保存在表中即可。然而,如果每次有人需要下一个号码时都必须更新一个表格,这流程会非常缓慢。这时应该使用一个自主事务,这样就不需要等待第一个会话提交其当前事务,然后才能生成下一个数字。因此,Oracle使用递归的、自主的事务来处理表更新,并且它通过在内存中计数并记住下一次需要更新表的时机来避免每次调用nextval都更新表。

自制”序列的一种常见策略是,在一个表中包含(序列名,最近使用的序列号)的列,然后编写一个函数,从表中选择相关行进行更新,增加编号,更新表,并将编号提供给最终用户,这正是Oracle内在的机制。

您可以通过查询视图 user_sequences 来查看序列的数据库映像。假设我刚刚创建了一个名为s1的序列,图3.1是一个查询创建序列后立即给出的结果,和一次调用获取 s1.nextval 后得到的结果:

selectmin_value, max_value, increment_by, cache_size, last_number, cycle_flag, order_flag
from user_sequences
where sequence_name = 'S1'
/

图7.1

如果你有DBA权限,你可以进一步找到序列的 object_id,然后查询视图所基于的字典表(seq$)。以下运行了两次查询,一次在第一次调用 s1.nextval 之前,另一次是刚刚调用 s1 之后:

select minvalue, maxvalue, increment$, cache, highwater, cycle#, order$ 
from seq$ 
whereobj# = 124874
;

图7.2

如果你的账户已被授权,可以通过动态性能视图 v$_sequences 查看内存中的信息:

selectmin_value, max_value,increment_by, cache_size, highwater,cycle_flag, order_flag, nextvalue
fromv$_sequences
whereobject# = 124874
/

第一次调用s1.nextval之后,我只查询了一次视图(在第一次调用nextval时,序列才会出现在视图中):

图7.3

动态性能视图的列 nextvalue 保存了下次用户调用 s1.nextval 时将提供的值。

三个视图中都有一个“highwater”值(在图7.1视图user_sequences中称为“last_number”)。当对s1.nextval 的调用返回 highwater 中显示的值(highwater和nextvalue相同)时,进行调用的会话将执行并提交递归事务,将增量值添加到当前 highwater 并更新 seq$ 表。

“缓存”不是传统意义上的缓存,它只是一对数字(无论您设置的序列缓存大小有多大):当前值和提升highwater 后的值。为序列设置大型缓存不会造成资源损失,所以在大多数情况下,您应该尽可能使用大的cache。

1.直接删除序列,然后重新创建并且设置序列的初始值为希望的数据

drop sequence "SEQ_StockFlow_ID";create sequence "SEQ_StockFlow_ID"increment by 1start with 1000 --你想要的值MAXvalue 9999999999999999;

2、修改序列的每次增加的值,然后再修改回每次自增1

-- 修改序列alter sequence "SEQ_StockFlow_ID" increment by 13500;   -- 查看序列select "SEQ_StockFlow_ID".nextval from dual;-- 修改序列alter sequence "SEQ_StockFlow_ID" increment by 1;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2815418.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

java 反射机制 (一)

java反射机制: 即通过外部文件配置,不修改文件源码的情况下,来控制程序,也符合设计模式的OCP原则(开闭原则:不修改源码,扩容原则) Java Reflection 1.反射机制允许程序在执行期间…

Spring中的事务和事务的传播机制

事务是一组操作的集合,不可以被分割。事务会把所有的操作作为一个整体,这组操作要么全部成功,要么全部失败。 事务有三种操作: 开启事务;提交事务;回滚事务。 如果代码的执行逻辑是这样: 开…

dolphinscheduler海豚调度(三)SQL任务

在之前的博文中,我们已经介绍了DolphinScheduler海豚调度的基本概念和模块,安装部署和元数据切换,以及Shell任务的实践。今天,让我们来深入探讨DolphinScheduler中另一种常见的任务类型:SQL任务。 SQL任务是DolphinSc…

弹窗内容由后端返回,如何让点击按钮的事件交由前端控制?

一、场景 背景:因为系统里经常有新活动或者公告需要通知所有用户,希望前端维护的这个弹窗里的内容可以由后端接口返回。这样就不需要每次上新活动的时候,前端项目都发版了。因此,前端维护了这个弹窗和它的关闭事件,至…

人工智能之Tensorflow常用API

TensorFlow的计算表现为数据流图,所以tf.Graph类中包含一系列表示计算的操作对象(tf.Operation),以及在操作之间流动的数据–张量对象(tf.Tensor)。 Graph tf.Graph类包含图相关的API操作,可以在jupyter notebook导入tensorflow之后执行hel…

前端Vue项目无法启动服务,提示无 ‘dev‘ npm的脚本问题解决

目录 一、问题详情 二、问题解决 一、问题详情 上周还能运行的项目,今天突然无法执行了,连最基本的启动按钮也没有了,所有的项目本地都突然跑不起来了,附上截图。 二、问题解决 后来排查的根本原因有点奇葩,是因为…

【踏雪无痕的痕四】——0到底是有还是没有?

目录 一、背景介绍三、过程1.0的历史发展?2.如何将0讲给一个刚上一年级的孩子?3.0的边界和意义?4.那四年,到底在培养什么?和0有什么关系? 四、总结 一、背景介绍 最近在看一年级数学,其中介绍到…

javaWeb个人学习02

会话技术 会话: 用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束.在一次会话中包含多次请求和响应 会话跟踪: 一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一个浏览器,以便在同一次会话的多次请求之间共享数据 会话跟踪方案: …

艺术作品展示图片介绍PR相册视频模板

高级感艺术风格摄影、绘画作品展示文字介绍PR图片相册照片视频模板mogrt下载。 Premiere Pro 2023及以上版本,不需要插件,高清(19201080)分辨率/30fps,易于定制,持续时间01:00秒,包含PDF帮助文件…

猜猜心里数字(个人学习笔记黑马学习)

1.定义一个变量,数字类型,内容随意 2.基于input语句输入猜想的数字,通过if和多次elif的组合,判断猜想数字是否和心里数字一致 num5if int(input("请输入第一次猜想的数字:"))5:print("猜对了&#xff0…

三分钟一起了解工作流拖拽

低代码技术平台是如今深受很多行业喜爱的得力助手,也是实现提质增效的办公效果的有力武器。作为一家专业研发低代码技术平台的服务商,流辰信息的IBPS在很多行业领域中得到了大家的认可和喜爱,其中,工作流拖拽功能也是IBPS的主要功…

基于Springboot的计算机知识竞赛网站(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的计算机知识竞赛网站(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结…

【严格递增】2972统计移除递增子数组的数目 II

作者推荐 动态规划的时间复杂度优化 本文涉及知识点 严格递增 子数组 LeetCode2972. 统计移除递增子数组的数目 II 给你一个下标从 0 开始的 正 整数数组 nums 。 如果 nums 的一个子数组满足:移除这个子数组后剩余元素 严格递增 ,那么我们称这个子…

【王道数据结构】【chapter7查找】【P309t10】

边那些一个递归算法&#xff0c;在一棵有n个几点的、随机建立起来的二叉排序树上查找第k(1<k<n)小的元素并返回指向该节点的指针。要求算法的平均时间复杂度为O(log2n).二叉排序树的每个结点中除data,lchild,rchild等数据成员外&#xff0c;增加一个count成员&#xff0c…

贪心算法

贪心算法 例题1、股票买卖题目信息思路题解 2、货仓选址题目信息思路题解 3、糖果传递题目信息思路题解 4、雷达设备题目信息思路题解 例题 1、股票买卖 题目信息 思路 相邻两天&#xff0c;后>前&#xff0c;则交易一次 题解 #include <bits/stdc.h> #define en…

Ansible script 模块 该模块用于将本机的脚本在被管理端的机器上运行。Ansible服务执行本机脚本

目录 过程首先&#xff0c;我们写一个脚本&#xff0c;并给其加上执行权限直接运行命令来实现在被管理端执行该脚本验证错误演示 过程 该模块直接指定脚本的路径即可 首先&#xff0c;我们写一个脚本&#xff0c;并给其加上执行权限 vim /tmp/df.sh编辑脚本内容 这个脚本内容…

动态住宅IP vs 静态住宅IP,如何选择适合你的海外住宅IP?

随着数字时代的发展&#xff0c;网络已经成为了我们日常生活中不可或缺的一部分。在海外留学、旅游、工作或者进行电子商务等活动时&#xff0c;一个合适的住宅IP可以帮助我们保护个人隐私、确保网络连接的稳定性、提高在线服务的可靠性等。因此&#xff0c;选择适合自己的住宅…

【C++】树形关联式容器set、multiset、map和multimap的介绍与使用

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.关联式容器 2.键…

【DDD】学习笔记-领域驱动设计体系

从统一语言到限界上下文&#xff0c;从限界上下文到上下文映射&#xff0c;从领域分析建模到领域设计建模&#xff0c;再从领域设计建模到领域实现建模&#xff0c;我将软件架构设计、面向对象设计、场景驱动设计和测试驱动开发有机地融合起来&#xff0c;贯穿于领域驱动设计的…

Python炒股自动化(2):获取股票实时数据和历史数据

如果你是一位大佬&#xff0c;看我前面的分享即可&#xff0c;相信你有自己的思路&#xff0c;或者已经有了成熟的策略&#xff0c;你需要的只是API接口来实现你的想法&#xff0c;前面的分享是你需要的&#xff0c;这些是给刚开始接触程序交易的朋友分享的。 前面发了股票程序…