PLSQL入门与精通(第19章,Sequence的不连续性)

第19回“存储过程事例2(保证连续性的发番处理)”前篇 2012.05.07 推特 这次与其说是过程的事例,不如说主要介绍连续号码的发号方法的定式,介绍将其存储过程化的方法。实际上,这是常见的过程事例。 暂且从上次的话开始继续着,不过,没有读上一次的人也只读这一次也没关系。
上次,作为存储过程的例子,说明了订单登记处理(PROC订单受理过程)。
内容是,检查该产品的库存数,如果不是库存不足的话就登记订单,相应产品的库存数只减少该订单的数量。
在这一连串的处理过程中,有对库存表的SELECT、
条件判定的IF文、对订单表的INSERT、对库存表的UPDATE等,
一系列的交易处理。

在这个过程中,我们取到了订单表时的主键(SEQ订购ID),这个主键用到的是Oracle的顺序对象。
对于Oracle来说,使用顺序对象是最简单且性能最好的方法,但缺点是不能保证是连续的序列号。
至于理由如下:
交易异常的时候,即使交易被ROLLBACK了,顺序对象的编号值也不会回滚。
例如,在某个事务中,从排序对象中获取当前值是“10”,接着该值进行INSERT,结果异常需要将该交易进行ROLLBACK。
如果继续做下一次处理的话,不是“10”而是在下一个值“11”。
所以在这种状态下,如果COMMIT交易的话,表中登记的不是“10”
而是11。也就是吧10跳过了,不连续了。
所以,Oracle顺序对象不会应为ROLLBACK而返回到原始值,所以可能会编号不连续。
或者,排序对象默认会在存储器中缓存20个编号,可能会因为某些原因(长时间未获取排序值或实例故障等)而丢失存储器信息。 在这种情况下,因为序列会跳过飞,所以不能连续。
但是,根据终端用户的需求,有必须保证连续号码的情况。 在这种情况下,不能使用oracle序对象,需要用新的方式。
需要增加一个排序表来存放这个序列字段。
然后,在发号处理中,将该编号加上1后的值作为新号码使用。 这样的话,即使取消了交易,更新顺序表也会在交易范围内,所以不会丢失号码。
例子如下:
SQL>CREATE TABLE 顺序
2(发号单位 VARCHAR2(20)PRIMARY KEY,
3 序号 NUMBER)
4 /

表格创建成功。

在这张表中,存储的事示“已经发生过编号”的数据。
在上次的处理中,订单的订购ID是到2号为止,所以将意味着顺序表中已经存储了“订单2号”。
SQL>INSERT INTO 顺序 VALES('订购ID’,2);
创建了一行。
SQL> COMMIT;
提交完成。

这里,假设有顾客表这个表,那个表的顾客ID列预先登记表示
「顾客ID,到100号已经编号完毕」的数据。

SQL>INSERT INTO顺序VALES('顾客ID’,100);
创建了一行。
SQL> COMMIT;

此时,顺序表中的数据如下所示。

SQL>SELECT * FROM 顺序;
发号单位编号
‘’------------------------------
订单
ID 2
顾客ID 100

到此为止。下次对顺序表继续说明

猜你喜欢

转载自blog.csdn.net/niusr_1980_01/article/details/114181577