使用序列的错误ORA-02287

今天一个开发的同事问我一个问题,说在执行一条sql语句的时候报了ORA错误,脑海中删除了各种权限的问题之后,他提供给我的错误还是在我预料之外。
ERROR at line 1:
ORA-02287: sequence number not allowed here

这个问题看错误信息是很明显和sequence有关的。但是为什么会报出这个错误呢,在几封邮件交流之后,问题就明朗起来,
语句是类似下面这样的结构,
insert into customer(xxxxx,xxxxx,xxx...............)
select distinct xxxxx,seq_value.nextval,xxxx,xxxx,xxx... from new_table group by xxx,xxx,xxx,xxx;
真实的脚本洋洋洒洒一大页,各种子查询,表关联,函数处理,看起来还是需要些耐心的。简缩之后就是上面的结构,
这个Insert采用了子查询来插入数据,根据和开发的沟通,是需要提供一个补丁,做修复数据所用,所以会有大量的数据过滤操作。
插入数据的时候使用seq_value.nextval也还是很常见的,怎么会报出错误了呢,按照这个语句的结构发现还是最开头的distinct和group操作导致的,这种数据的统计分析操作让本来就不确定的sequence值更加不确定,所以斟酌再三还是建议他们先创建一个临时表,
不涉及序列的操作,只对序列之外的数据通过distinct,group by过滤之后,在insert的时候对刚创建的临时表和序列结合起来,一次插入。
伪代码类似下面的形式,
create table temp_tab as select distinct xxxxxx   from xxxx  group by xxxxxx;
insert into customer(xxxxx,xxxx) select xxxx,seq_vvalue.nextval from temp_tab;

我们来简答模拟一下这个问题。
首先为了不影响原有的sequence,我们可以创建一个类似的sequence,然后在脚本中替换即可,这样也不会对原有环境的sequence值造成影响。
CREATE SEQUENCE  "NEW_SEQ"  MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1012852 CACHE 20 NOORDER  NOCYCLE
然后我们创建一个表
create table new_test( id1 number,id2 number,name varchar2(30));
然后尝试distinct和group by 操作,发现都不可以。
n1@TEST11G> select new_seq.nextval,id1,id2,name from new_test group by id1,id2,name;
select new_seq.nextval,id1,id2,name from new_test group by id1,id2,name
               *
ERROR at line 1:
ORA-02287: sequence number not allowed here

n1@TEST11G> select distinct new_seq.nextval,id1,id2,name from new_test;
select distinct new_seq.nextval,id1,id2,name from new_test
                        *
ERROR at line 1:
ORA-02287: sequence number not allowed here
其实这个问题的原因还是很容易理解的,这种sequence值的动态不确定性,很容易出问题。其实不光使用distinct,group by 会有问题,很多相关的操作都是如此。
比如union,union all
select new_seq.nextval,id1,id2,name from new_test 
union all
select new_seq.nextval,id1,id2,name from new_test 

minus操作。
select new_seq.nextval,id1,id2,name from new_test 
minus
select new_seq.nextval,id1,id2,name from new_test 

使用In子查询
select new_seq.nextval id1,id2,name from new_test  where id1 in (select new_seq.nextval from new_test )

order by操作
select new_seq.nextval,id1,id2,name from new_test order by id2;

换个角度来看,对于这类问题,也可以使用临时表来处理,也可以使用pl/sql来处理,都能达到比较目的,另外一个角度来说,对于sequence的使用,大家一般都认为是取之不尽,用之不竭,感觉大量使用时应该的,在很多时候还是需要好好斟酌一下,有些补丁或者临时的处理是否一定需要使用到
序列,序列资源也是很宝贵的资源,如果在测试脚本中做了大量的自增处理也是很大的浪费。

时间: 2024-09-29 08:54:22

使用序列的错误ORA-02287的相关文章

Oracle 错误总结及问题解决 ORA

参考地址 ORA-00001: 违反唯一约束条件 (.)错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常.ORA-00017: 请求会话以设置跟踪事件ORA-00018: 超出最大会话数ORA-00019: 超出最大会话许可数ORA-00020: 超出最大进程数 ()ORA-00021: 会话附属于其它某些进程:无法转换会话ORA-00022: 无效的会话 ID:访问被拒绝ORA-00023: 会话引用进程私用内存:无法分离会话ORA-00024: 单一进程模式下不允许从多个进程注册

ORACLE错误一览表 方便查询_oracle

ORACLE错误一览表,方便大家查询! ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出最大进程数 () ORA-00021: 会话附属于其它某些进程:无法转换会话 ORA-00022: 无效的会话 ID:访问被拒绝 ORA-00023: 会话引用进程私用内存:无法分离会话 ORA-00024: 单一进程模式下不允许从多个进程注册 ORA-000

宽带连接错误代码

  我们日常使用电脑连接宽带出现错误时,都会返回一个错误代码,每个代码对应的是不同的错误提示. 600 某操作处于挂起状态. 发生内部错误,重新启动计算机,以确保所有最近所作的配置更改都能生效. 601 检测到无效的端口句柄. 发生内部错误,重新启动计算机,以确保所有最近所作的配置更改都能生效. 602 指定的端口已打开. 网络连接试图使用的com端口正在被其他活动的网络连接或其他的进程(例如:诸如传真程序之类的电话线路监视程序)使用.退出阻止使用com端口的应用程序. 603 呼叫人的缓冲区太

Java核心技术 卷Ⅰ 基础知识(原书第10版)

Java核心技术系列 Java核心技术 卷Ⅰ 基础知识 (原书第10版) Core Java Volume I-Fundamentals (10th Edition) [美] 凯S.霍斯特曼(Cay S. Horstmann) 著 周立新 陈 波 叶乃文 邝劲筠 杜永萍 译 图书在版编目(CIP)数据 Java核心技术 卷Ⅰ 基础知识(原书第10版) / (美)凯S. 霍斯特曼(Cay S. Horstmann)著:周立新等译. -北京:机械工业出版社,2016.8 (Java核心技术系列) 书

使用Oracle实现实时通信

oracle 由于Oracle不提供用于实时输出消息的工具, Oracle数据库开发者总是要面临实时监视他们的储备过程执行的挑战.他们必须使用dbms_output.put_line调用,这个调用直到过程完成才返回结果. 在本文中,我想演示如何从Oracle8i数据库直接发送电子邮件,作为一种实时通信解决方案.这样我们要监视存储过程就不再需要等待它们完成了,这样的方法还为开发者提供了其他的一些好处: . 可以在几分钟内调试一些很长的批处理过程,而不需要等几个小时: . 计算用于指定代码块所需的执

Oracle数据库表空间恢复方案

oracle|恢复|数据|数据库 一. 用户表空间 错误: 在启动数据库时出现ORA-01157,ORA-01110或操作系统级错误例如ORA-07360,在关闭数据库(使用shutdown normal或shutdown immediate) 时将导致错误ORA -01116,ORA-01110以及操作系统级错误ORA-07368 解决,以下有两种解决方案: 1.用户的表空间可以被轻易地重建 即最近导出的对象是可用的或表空间中的对象可以被轻易地重建等.在这种情况下,最简单的方法是offline

ORACLE表空间恢复方案

一. 用户表空间 错误: 在启动数据库时出现ORA-01157,ORA-01110或操作系统级错误例如ORA-07360, 在关闭数据库(使用shutdown normal或shutdown immediate) 时将导致错误ORA -01116,ORA-01110以及操作系统级错误ORA-07368 解决,以下有两种解决方案: 1.用户的表空间可以被轻易地重建 即最近导出的对象是可用的或表空间中的对象可以被轻易地重建等.在这种情况下,最简单的方法是offline并删除该数据文件,删除表空间并重

详解如何用 LSTM 自动识别验证码

这是去年博主心血来潮实现的一个小模型,现在把它总结一下.由于楼主比较懒,网上许多方法都需要切割图片,但是楼主思索了一下感觉让模型有多个输出就可以了呀,没必要一定要切割的吧?切不好还需要损失信息啊!本文比较简单,只基于传统的验证码. Part 0 模型概览 从图片到序列实际上就是Image2text也就是seq2seq的一种.encoder是Image, decoder是验证码序列.由于keras不支持传统的在decoder部分每个cell输出需要作为下一个rnn的cell的输入(见下图),所以我

ORACLE数据库日常维护知识点总结_oracle

首先要说的是,不同版本数据库提供的系统表会有不同,你可以根据数据字典查看该版本数据库所提供的表 like this: select * from dict where table_name like '%SESSION% '; 就可以查出一些表,然后根据这些表就可以获得会话信息. 像这样就是 查询当前正在操作的会话: SELECT SID, SERIAL#, STATUS, USERNAME, SCHEMANAME, OSUSER,TERMINAL, MACHINE, PROGRAM, A.NA