MySQL下创建序列及创建自定义函数方法介绍

工作过程中需要将基于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

时间: 2024-11-06 14:08:00

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

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

转载地址:http://www.2cto.com/database/201212/177382.html 一.自定义函数(UDF)的特性和功能  www.2cto.com 函数能分返回字符串,整数或实数; 可以定义一次作用于一行的简单函数,或作用于多行的组的集合函数; 二.基本操作 1.创建自定义函数 CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|INTEGER|REAL} BEGIN //函数实现的语句 END; aggre

MySQL数据库高级(二)——自定义函数

MySQL数据库高级(二)--自定义函数 一.自定义函数简介 自定义函数 (user-defined function UDF)是一种对MySQL扩展的途径,其用法和内置函数相同.自定义函数的两个必要条件:A.参数B.返回值(必须有).函数可以返回任意类型的值. 二.自定义函数的使用 1.自定义函数语法 CREATE?FUNCTION?function_name(parameter_nametype,[parameter_name type,...]) RETURNS?{STRING|INTEG

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

如果我是C罗 原文 ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍 sequence在ORACLE中应用十分广泛,就是序列号的意思,会自动增加指定变数,如逐次增加1或者2或者其他. 1.创建序列 Create Sequence 你首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE 权限 CREATE SEQUENCE CUX_DEMO_SEQUENCEMINVALUE 1MAXVALUE 99999999999START WITH 1000

linux下常见内存异常查证工具和方法介绍

linux下常见内存异常查证工具和方法介绍 内存异常导致的异常往往很难查证,本文介绍在linux下的各种常见内存异常的查证工具和方法. 1.访问空指针/未初始化指针 这个是最简单的内存异常了,只要能够生成coredump文件,可以快速定位问题代码. 开启coredump 部分环境下默认不会生成coredump,需要运行如下命令:ulimit -c unlimited //unlimited表示不限制coredump文件大小,也可以指定一个最大文件大小. 定制core文件名 默认的coredump

mysql的学习(七)-自定义函数和流程控制

DELIMITER // (设置结束符 其实我也不太明白为啥要这样 记住就行把) CREATE FUNCTION ym_date(mydate DATE) (创建函数 函数名字(参数)) RETURNS VARCHAR(20) (指定函数的返回类型) BEGIN (函数开始,如果函数只有一句可以省略bigin和end) RETURN DATE_FORMAT(mydate,%Y-%m); (函数体) END// (函数结束) DELIMITER ; (把结束符再变成;) CREATE FUNCTI

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

转至:https://stackoverflow.com/questions/12113699/get-top-n-records-for-each-group-of-grouped-results 通过分组的排序及序号获取条数信息,可以使用到索引,没测试性能,不知道和mssql的cross apply性能差异性为多少,只是能实现相应的效果. 1 #MySQL 5.7.12 2 #please drop objects you've created at the end of the scrip

PHP可变长函数方法介绍

1.三个重要函数 func_num_args()  返回实参个数 func_get_arg(i)    返回某个实参的值       func_get_args()        以数组的形式返回实参的所有值 示例: <?php function foo() { $numargs = func_num_args(); echo "Number of arguments: $numargs<br />\n"; if ($numargs >= 2) { echo &

MySQL学习笔记-自定义函数

MySQL学习笔记-自定义函数 1.自定义函数简介 自定义函数:用户自定义函数(user-defined function,UDF)是一种对MySQL扩展的途径,其用法与内置函数相同 自定义函数的两个必要条件:(1)参数  (2)返回值 自定义函数: 创建自定义函数 CREATE FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL} routine_body 关于函数体: 1.函数体可以由合法的SQL语句构成: 2.函数体可以是

MYSQL的自定义函数

自定义函数 用户自定义函数是一种对MYSQL扩展的途径,其用法与内置函数相同 函数可以返回任意类型的值,同样可以接收这些类型的参数 函数体由合法的SQL语句构成 函数体可以是简单的SELECT或INSERT语句 函数体如果为复合结构则使用BEGIN...END语句 复合结构可以包含声明,循环,复制结构 创建不带参数的自定义函数 第一步CREATE  FUNCTION  函数名 ()  FETURNS  字符串长度如VARCHAR(30) 第二步RETURN  类型(如DATE)_FORMAT