工作过程中需要将基于DB2数据库的应用以及数据迁移到MySQL中去,在原应用中,大量使用了SEQUENCE,考虑尽量减少代码的修改,决定在迁移后的应用中继续保留SEQUENCE的使用,这就要求在MySQL中寻找替代SEQUENCE的解决方案。

在DB2中创建一个SEQUENCE的方法如下:

DROP SEQUENCE TRZ_MEMBER.SEQ_TRZ_MEMBER_NO;
CREATE SEQUENCE TRZ_MEMBER.SEQ_TRZ_MEMBER_NO
AS BIGINT
INCREMENT BY 1
START WITH 10000000000
MAXVALUE 99999999999
NO CYCLE
CACHE 20
ORDER;

MySQL自增长与Oracle(DB2)序列的区别:

自增长只能用于表中的其中一个字段;

自增长只能被分配给固定表的固定的某一字段,不能被多个表共用;

自增长会把一个未指定或NULL值的字段自动填上。

要想在MySQL中替代SEQUENCE功能需要做一下几件事:

1:建立SEQUENCE表,存储多条SEQUENCE信息;

2:完成自定义函数的定义,在程序中通过该函数完成生成的序列的获取;

接下来将介绍两种生成方式,一种是非并发方式,一种是并发方式,前一种不能够处理并发访问中存在的问题,后一种则能够处理,两种方式的第一步都相同,就是创建SEQUENCE表:

非并发方式:

一:创建SEQUENCE表:

DROP TABLE
IF EXISTS sequence;
CREATE TABLE
sequence
(
name VARCHAR(50) NOT NULL,
current_value BIGINT NOT NULL,
increment INT NOT NULL DEFAULT 1,
PRIMARY KEY (name)
)
ENGINE=InnoDB;

该表用来存储多条sequence信息,每条sequence为一个序列,其效果等同于之前介绍的DB2中的sequence。假设需要替换DB2中的SEQ_TRZ_MEMBER_NO(如前定义),则插入MySQL中表sequence的插入语句如下:

INSERT INTO sequence VALUES ('SEQ_TRZ_MEMBER_NO',10000000000,1);

二:创建MySQL自定义函数,用以获取当前sequence值:

1:首先明确的是,自定义函数是对MySQL提供的函数库的一种补充,用来完成自定义功能,新建MySQL函数必须通过MySQL Commond Line键入命令行的方式进行创建,而不能通过第三方提供的图形化数据库操作软件来创建;

2:首先提供一个范例,好有一个总体的认识:

DELIMITER $$
DROP FUNCTION IF EXISTS currval;
CREATE FUNCTION currval (seq_name VARCHAR(50))
RETURNS BIGINT
BEGIN
DECLARE c_value BIGINT DEFAULT 0;
SET c_value = 0;
SELECT current_value into c_value
FROM sequence
WHERE name = seq_name;
RETURN c_value;
END $$
DELIMITER ;

该函数的功能为返回指定序列的当前值。

其中第一行代码(DELIMITER $$ )定义一个结束标识符,因为MySQL默认是以分号作为SQL语句的结束符的,而函数体内部要用到分号,所以会跟默认的SQL结束符发生冲突,所以需要先定义一个其他的符号作为SQL的结束符。没有加这个定义的话会报如下错误:

错误码: 1064

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'end' at line 1

第二行(DROP FUNCTION IF EXISTS currval; )是删除同名的类,不然如果已经存在了同名函数,会报如下错误:

错误码: 1304

FUNCTION currval already exists

第三,第四行定义函数名称和函数返回值;
而函数体必须定义在Begin和End中间。
通过MySQL Commond Line执行后效果如下所示:

通过如下语句验证效果:

该函数只完成了获取当前序列值的作用,还需要定义一个函数来完成获取下一个序列值的功能,代码如下所示:

DROP FUNCTION IF EXISTS nextval;
DELIMITER $$
CREATE FUNCTION nextval (seq_name VARCHAR(50))
RETURNS BIGINT
CONTAINS SQL
BEGIN
UPDATE sequence
SET current_value = current_value + increment
WHERE name = seq_name;
RETURN currval(seq_name);
END $$
DELIMITER ;

该函数用来获取下一个序列值,在MySQL Commond Line中执行后的结果如下所示:

通过如下语句验证函数是否生效:

SELECT NEXTVAL('SEQ_TRZ_MEMBER_NO');

至此非并发方式的sequence生成方式就实现完了。要想使得sequence的生成能够处理并发的方式,只需要少做修改即可。

并发生成方式:

sequence的并发生成方式同非并发生成方式都需要建立sequence表,如下:

一:创建SEQUENCE表:

DROP TABLE
IF EXISTS sequence;
CREATE TABLE
sequence
(
name VARCHAR(50) NOT NULL,
current_value BIGINT NOT NULL,
increment INT NOT NULL DEFAULT 1,
PRIMARY KEY (name)
)
ENGINE=InnoDB;

插入定义的序列:

INSERT INTO sequence VALUES ('SEQ_TRZ_MEMBER_NO',10000000000,1);

二:自定义函数实现:

DROP FUNCTION IF EXISTS seq;
DELIMITER $$
CREATE FUNCTION seq(seq_name char (20)) returns BIGINT
BEGIN
UPDATE sequence SET current_value=last_insert_id(current_value+increment) WHERE name=seq_name;
RETURN last_insert_id();
END $$
DELIMITER;

函数内部调用了MySQL内部提供的last_insert_id()函数完成并发控制。

而有关于last_insert_id的相关资料请参考:
http://it.100xuexi.com/view/otdetail/20120619/73a6cc8f-36b8-4b70-8904-57c18d3ab385.html

文中代码部分引自:http://meetrice.iteye.com/blog/89426

http://www.blogjava.net/Skynet/archive/2011/03/23/301847.html

MySQL下创建序列及创建自定义函数方法介绍的更多相关文章

  1. ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍

    如果我是C罗 原文 ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍 sequence在ORACLE中应用十分广泛,就是序列号的意思,会自动增加指定变数,如逐次增加1或者2或者 ...

  2. Mysql5.7创建存储过程中调用自定义函数报错Not allowed to return a result set from a function

    因为很多存储过程都会共用一段sql语句,所以我把共用的sql封装成一个自定义函数 AddCapital(); 然后通过存储过程调用,创建存储过程会报错1415,Not allowed to retur ...

  3. 【转】MYSQL入门学习之十三:自定义函数的基本操作

    转载地址:http://www.2cto.com/database/201212/177382.html 一.自定义函数(UDF)的特性和功能  www.2cto.com           函数能分 ...

  4. Oracle创建序列,Oracle创建序列语法

    -- Oracle创建序列 Create sequence CREATE SEQUENCE SEQ_SINGER -- 序列名称  START WITH 2 -- 开始数字  MAXVALUE 999 ...

  5. MySql cmd下的学习笔记 —— 有关常用函数的介绍(数学函数,聚合函数等等)

    (一)数学函数 abs(x)              返回x的绝对值 bin(x)               返回x的二进制(oct返回八进制,hex返回十六进制) ceiling(x)      ...

  6. mysql下分组取关联表指定提示方法,类似于mssql中的cross apply

    转至:https://stackoverflow.com/questions/12113699/get-top-n-records-for-each-group-of-grouped-results ...

  7. 【R】自定义函数方法

  8. PHP可变长函数方法介绍

    1.三个重要函数 func_num_args()  返回实参个数 func_get_arg(i)    返回某个实参的值       func_get_args()        以数组的形式返回实参 ...

  9. MySQL 创建自定义函数(2)

    说明:下面创建一个函数,调用自定义函数返回一个返回一个随机数. (1) 创建自定义函数

随机推荐

  1. 苹果没放弃手写笔 这样的iPad你想要吗?

    12 月 31 日,美国专利与商标局(The U.S. Patent and Trademark Office)当地时间周四批准了一项来自苹果的专利申请,该专利主要描述的是一种可以通过陀螺仪.无线通讯 ...

  2. 通过Nrgok映射外网调试微信

    一.注册账号 注册地址:http://www.ngrok.cc/login 登录系统,新增域名 二.下载客户端,修改配置文件 修改ngrok.cfg auth_token值登录平台管理系统可查看 su ...

  3. python 动态获取当前运行的类名和函数名的方法

    一.使用内置方法和修饰器方法获取类名.函数名 python中获取函数名的情况分为内部.外部,从外部的情况好获取,使用指向函数的对象,然后用__name__属性 复制代码代码如下: def a():pa ...

  4. 栈和队列在python中的实现

    栈和队列是两种基本的数据结构,同为容器类型.两者根本的区别在于: stack:后进先出 queue:先进先出 PS:stack和queue是不能通过查询具体某一个位置的元素而进行操作的.但是他们的排列 ...

  5. 七周七语言之用ruby做点什么

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/05/25/sevenlang-ruby/. 每学一 ...

  6. purcell的emacs配置中的自动补全功能开启

    标记一下,原文参看purcell的emacs配置中的自动补全功能开启 修改init-auto-complete.el文件 ;;(setq-default ac-expand-on-auto-compl ...

  7. Java对象创建过程补遗

    一.static修饰的东东是属于这个类的,是所有的该类的实例共享的,因此它们的初始化先于实例对象的初始化. 二.Java中没有静态构造方法,但是有静态代码块.当类中同时存在静态代码块和静态成员变量声明 ...

  8. 1029对c语言文法的理解

    <程序>→<外部声明>|<程序><外部声明> <外部声明>→<函数定义>|<声明> <函数定义>→< ...

  9. QtCharts模块在QtWideget中图表绘制(非QML)

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QtCharts模块在QtWideget中图表绘制(非QML)     本文地址:http:/ ...

  10. 【第二周】scrum站立会议

    1.站立会议:敏捷软件开发方法论Scrum的相关技术之一,是scrum的最佳实践 2.具体形式:每天的同一时间让团队成员面对面站立交流工作进展 3.功能: (1)让团队所有人都相互知道彼此的进展,了解 ...