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://www.mzph.cn/news/707327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

milvus upsert流程源码分析

milvus版本:v2.3.2 整体架构: Upsert 的数据流向: 1.客户端sdk发出Upsert API请求。 import numpy as np from pymilvus import (connections,Collection, )num_entities, dim 4, 3print("start connecting to Milvus") connections.connect("default",…

11.题目:编号3272 小蓝的漆房

题目&#xff1a; ###本题主要考察暴力&#xff0c;枚举&#xff0c;模拟 #include<bits/stdc.h> using namespace std; const int N1e410; int a[N],b[N]; int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int num;cin>>num;//样例个数循环for(int i…

socket套接字

前言 两个应用程序如果需要进行通讯最基本的一个前提就是能够唯一的标示一个进程&#xff0c;我们知道IP层的ip地址可以唯一标示主机&#xff0c;而TCP层协议和端口号可以唯一标示主机的一个进程&#xff0c;这样我们可以利用ip地址&#xff0b;协议&#xff0b;端口号唯一标示…

许战海矩阵|佐香园:“熟酱”的爆品战略

佐香园是辽宁帝华味精食品有限公司的主导品牌&#xff0c;是一个拥有自主研发与生产经营能力的民营企业&#xff0c;主要生产和销售香料、调味料以及食品添加剂等产品。该品牌自创办以来&#xff0c;一直坚持以市场为导向&#xff0c;走专业化发展之路&#xff0c;打造全方位的…

LACP——链路聚合控制协议

LACP——链路聚合控制协议 什么是LACP&#xff1f; LACP&#xff08;Link Aggregation Control Protocol&#xff0c;链路聚合控制协议&#xff09;是一种基于IEEE802.3ad标准的实现链路动态聚合与解聚合的协议&#xff0c;它是链路聚合中常用的一种协议。 链路聚合组中启用了…

TikTok矩阵系统的功能展示:深入解析与源代码分享!

今天我来和大家说说TikTok矩阵系统&#xff0c;在当今数字化时代&#xff0c;社交媒体平台已成为人们获取信息、交流思想和娱乐放松的重要渠道&#xff0c;其中&#xff0c;TikTok作为一款全球知名的短视频社交平台&#xff0c;凭借其独特的创意内容和强大的算法推荐系统&#…

【MQ05】异常消息处理

异常消息处理 上节课我们已经学习到了消息的持久化和确认相关的内容。但是&#xff0c;光有这些还不行&#xff0c;如果我们的消费者出现问题了&#xff0c;无法确认&#xff0c;或者直接报错产生异常了&#xff0c;这些消息要怎么处理呢&#xff1f;直接丢弃&#xff1f;这就是…

带大家做一个,易上手的家常蒜香菠菜

一捆 菠菜 四瓣蒜 蒜去皮切末 菠菜切段 多清洗几次 因为菠菜上面的土真的是太多了 菠菜下锅 加水煮一分钟左右 因为菠菜内的草酸成分非常高 所以这一步肯定是要的 然后将菠菜捞出来 干和叶子分开 锅中水倒掉 清洗一下 然后起锅烧油 下蒜末炒香 然后 下菠菜干 因为干熟的…

Python + Selenium —— 网页元素定位之标签名和链接文本定位

tag name tag name 为标签名定位&#xff0c;使用网页元素的标签名如a, div, input, span 等。 但是有一个问题&#xff0c;常见的标签名比如 在同一个页面上有非常多。会不会觉得 tag name 没什么用呢&#xff1f; 当然普通的模拟操作是不大有用&#xff0c;这个重复性实在…

笔记:GO1.19 带来的优化(重新编译juicefs)

## 背景 go编写的应用程序&#xff08;juicefs&#xff09;在k8s&#xff08;docker&#xff09;中运行&#xff0c;时不时出现 OOM Killed。 ## 分析 发现某些应用使用juicefs会导致内存使用飙升&#xff1b; k8s的pod给的内存资源&#xff1a;request 2G&#xff0c;limit…

基于springboot实现线上阅读系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现线上阅读系统演示 摘要 随着社会发展速度的愈来愈快&#xff0c;以及社会压力变化的越来越快速&#xff0c;致使很多人采取各种不同的方法进行解压。大多数人的稀释压力的方法&#xff0c;是捧一本书籍&#xff0c;心情地让自己沉浸在情节里面&#xff0c;以…

基于沁恒微 ch643q 多通道采集 adc 驱动层实现

一、代码 #include "main.h"/********************************************************************** fn ADC_Function_Init** brief Initializes ADC collection.** return none*/ void ADC_Function_Init(void) {ADC_InitTypeDef ADC_InitStructure …

pdffactory pro 8中文破解版

详细介绍 PdfFactory&#xff0c;PDF文档虚拟打印机&#xff0c;无须Acrobat即可创建Adobe PDF文件&#xff0c;创建PDF文件的方法比其他方法更方便和高效。支持将多个文档整合到一个PDF文件、增加字体和便签、PDF加密、去水印、压缩优化。 FinePrint&#xff0c;Windows虚拟…

【踩坑】修复xrdp无法关闭Authentication Required验证窗口

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 问题如下&#xff0c;时不时出现&#xff0c;有时还怎么都关不掉&#xff0c;很烦&#xff1a; 解决方法一&#xff1a;命令行输入 dbus-send --typemethod_call --destorg.gnome.Shell /org/gnome/Shell org.gn…

js 面试题--事件循环event loop--宏任务和微任务

1 事件循环event loop概念&#xff1a; js 是非阻塞单线程语言&#xff0c;js在执行过程中会产生执行环境&#xff0c;执行环境会按顺序添加到执行栈中&#xff0c;先执行同步栈中的任务&#xff0c;当遇到异步任务时会添加到task队列中&#xff0c;同步栈执行完后&#xff0c…

一文读懂什么是 OCR 识别

在数字化时代&#xff0c;信息处理和数据管理是企业运营的重要环节。然而&#xff0c;手工输入信息存在效率低和准确性低的问题&#xff0c;严重影响了企业的工作流程和决策过程。因此&#xff0c;OCR&#xff08;Optical Character Recognition&#xff09;识别技术的应用变得…

【Unity】导入IAP插件后依赖冲突问题 com.android.billingclient冲突

【Unity】Attribute meta-data#com.google.android.play.billingclient.version 多版本库冲突_unity billingclient-CSDN博客 打开mainTemplate.gradle 找到dependencies { } 在里面末尾加上如下&#xff1a; configurations.all {exclude group: com.android.billingclien…

uni-app 实现拍照后给照片加水印功能

遇到个需求需要实现&#xff0c;研究了一下后写了个demo 本质上就是把拍完照后的照片放到canvas里&#xff0c;然后加上水印样式然后再重新生成一张图片 代码如下&#xff0c;看注释即可~使用的话记得还是得优化下代码 <template><view class"content"&g…

单词倒排——c语言解法

以下是题目&#xff1a; 这个题中有三个点&#xff0c; 一个是将非字母的字符转换为空格&#xff0c; 第二是如果有两个连续的空格&#xff0c; 那么就可以将这两个连续的空格变成一个空格。 第三个点就是让单词倒排。 那么我们就可以将这三个点分别封装成三个函数。 还有就是…

特征融合篇 | YOLOv8 引入通用高效层聚合网络 GELAN | YOLOv9 新模块

今天的深度学习方法专注于如何设计最合适的目标函数,以使模型的预测结果最接近真实情况。同时,必须设计一个合适的架构,以便为预测提供足够的信息。现有方法忽视了一个事实,即当输入数据经过逐层特征提取和空间转换时,会丢失大量信息。本文将深入探讨数据通过深度网络传输…