现在的位置: 首页 > 综合 > 正文

Mysql存储过程(五)——SEQUENCE的实现

2018年01月30日 ⁄ 综合 ⁄ 共 1957字 ⁄ 字号 评论关闭

在 oracle 中, sequence 提供多表多字段可共用一个不重复值。 Mysql 中存在自增列,基本可以满足 PK 的要求。但自增列存在限制:

a. 只能用于表中的一个字段,一张不能同时存在两个以上的自增列 ;

b. 自增列必须被定义为 key ( PK 或 FK ) ;

c. 自增列不能被多个表共用 ;

d. 当 insert 语句不包括自增字段或将其值设置为 NULL 时,该值会自动填上。

                   在不要求字段顺序递增的情况下,可以在 Mysql 中实现序列:

         Sql code 5-1:

DROP TABLE IF EXISTS sequence;  
 
-- 建sequence表,指定seq列为无符号大整型,可支持无符号值:0(default)到18446744073709551615(0到2^64–1)。
CREATE TABLE sequence (
     name              VARCHAR(50) NOT NULL,  
         current_value     BIGINT UNSIGNED NOT NULL DEFAULT 0,  
         increment         INT NOT NULL DEFAULT 1,  
         PRIMARY KEY (name)   -- 不允许重复seq的存在。
) ENGINE=InnoDB;  
 
 
DELIMITER / 
 
DROP FUNCTION IF EXISTS currval /
 
CREATE FUNCTION currval(seq_name VARCHAR(50)) 
RETURNS BIGINT
BEGIN
         DECLARE value BIGINT;
         SELECT current_value INTO value
         FROM sequence
         WHERE upper(name) = upper(seq_name); -- 大小写不区分.
         RETURN value;
END;
/
 
DELIMITER ; 
 
 
DELIMITER /
 
DROP FUNCTION IF EXISTS nextval /
 
CREATE FUNCTION nextval (seq_name VARCHAR(50))  
RETURNS BIGINT  
BEGIN  
         DECLARE value BIGINT;
         UPDATE sequence  
         SET current_value = current_value + increment  
         WHERE upper(name) = upper(seq_name);
         RETURN currval(seq_name);  
END;
/
 
DELIMITER ; 
 
DELIMITER /
 
DROP FUNCTION IF EXISTS setval /  
 
CREATE FUNCTION setval (seq_name VARCHAR(50), value BIGINT)  
RETURNS BIGINT
BEGIN 
         UPDATE sequence  
         SET current_value = value  
         WHERE upper(name) = upper(seq_name);  
         RETURN currval(seq_name);  
END;
/
 
DELIMITER ;

 在 SQL 中使用序列:

         Sql code 5-2:

创建序列,往sequence表插入值即可:
mysql> insert into sequence set name='myseq';
查看当前已建序列:
mysql> select * from sequence;
+-------+---------------+-----------+
| name  | current_value | increment |
+-------+---------------+-----------+
| myseq |             0 |         1 |
+-------+---------------+-----------+
1 row in set (0.00 sec)
获得序列的下一个值,第一次使用,因此值为1:
mysql> select nextval('myseq');
+------------------+
| nextval('myseq') |
+------------------+
|                1 |
+------------------+
1 row in set (0.00 sec)

 在存储过程中使用序列(以 sql code 1-1 中创建的 testproc 表为例),此存储过程返回插入后的 ID ,如果插入失败,则返回 -1 :

    sql code 5-3:

create procedure test_sequence(IN i_name VARCHAR(100),
         OUT o_ret BIGINT)
BEGIN
         DECLARE EXIT HANDLER FOR SQLWARNING,NOT FOUND,SQLEXCEPTION set o_ret = -1;
         set o_ret = nextval('myseq');
         INSERT INTO testproc VALUES (o_ret,i_name);
         INSERT INTO testproc3 VALUES (o_ret,i_name);
END;

抱歉!评论已关闭.