mysql 自增序列

 

 

1:原理是在建立一个触发器TRIGGER tri_NewBH  在table插入时执行序列计算

 mysql> CREATE TABLE tb(BH CHAR(16),content VARCHAR(20),`date` DATETIME,val INT);
Query OK, 0 rows affected (0.05 sec)

mysql>
mysql>
mysql> DELIMITER $$
mysql> DROP TRIGGER IF EXISTS tri_NewBH $$
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql>
mysql> CREATE TRIGGER tri_NewBH BEFORE INSERT ON tb
    -> FOR EACH ROW
    -> BEGIN
    ->     DECLARE dt CHAR(8);
    ->     DECLARE bh_id CHAR(16);
    ->     DECLARE number INT;
    ->     DECLARE new_bh VARCHAR(16);
    ->
    ->     SET dt = DATE_FORMAT(CURDATE(),'%Y%m%d');
    ->
    ->     SELECT
    ->         MAX(BH) INTO bh_id
    ->     FROM tb
    ->     WHERE BH LIKE CONCAT(dt,'%');
    ->
    ->     IF bh_id = '' OR bh_id IS NULL THEN
    ->         SET new_bh = CONCAT(dt,'00000001');
    ->     ELSE
    ->         SET number = RIGHT(bh_id,8) + 1;
    ->         SET new_bh =  RIGHT(CONCAT('00000000',number),8);
    ->         SET new_bh=CONCAT(dt,new_bh);
    ->     END IF;
    ->
    ->     SET NEW.BH = new_bh;
    -> END$$
Query OK, 0 rows affected (0.09 sec)

mysql>
mysql> DELIMITER ;
mysql> INSERT INTO tb(content,`date`,val) VALUES('LiangCK','2009-05-11',20);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO tb(content,`date`,val) VALUES('LiangCK','2009-05-11',20);
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO tb(content,`date`,val) VALUES('LiangCK','2009-05-11',20);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO tb(content,`date`,val) VALUES('LiangCK','2009-05-11',20);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO tb(content,`date`,val) VALUES('LiangCK','2009-05-11',20);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO tb(content,`date`,val) VALUES('LiangCK','2009-05-11',20);
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO tb(content,`date`,val) VALUES('LiangCK','2009-05-11',20);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM tb;
+------------------+---------+---------------------+------+
| BH               | content | date                | val  |
+------------------+---------+---------------------+------+
| 2009051100000001 | LiangCK | 2009-05-11 00:00:00 |   20 |
| 2009051100000002 | LiangCK | 2009-05-11 00:00:00 |   20 |
| 2009051100000003 | LiangCK | 2009-05-11 00:00:00 |   20 |
| 2009051100000004 | LiangCK | 2009-05-11 00:00:00 |   20 |
| 2011051200000001 | LiangCK | 2009-05-11 00:00:00 |   20 |
| 2011051200000002 | LiangCK | 2009-05-11 00:00:00 |   20 |
| 2011051200000003 | LiangCK | 2009-05-11 00:00:00 |   20 |
+------------------+---------+---------------------+------+
7 rows in set (0.00 sec)



 

 

2.下面就是另外一个的实现方案:

原理是创建一个专门记录序列的表sequence,记录有当前序列号,序列的间隔如+1

 


DROP TABLE IF EXISTS sequence;/*创建记录当前序列的表*/  
CREATE TABLE sequence (  
name              VARCHAR(50) NOT NULL,  
current_value INT NOT NULL,  
increment       INT NOT NULL DEFAULT 1,  
PRIMARY KEY (name)  
) ENGINE=InnoDB;  
INSERT INTO sequence VALUES ('MovieSeq',3,5);  
DROP FUNCTION IF EXISTS currval;  
DELIMITER $/*创建一个获取当前序列的function*/  
CREATE FUNCTION currval (seq_name VARCHAR(50))  
RETURNS INTEGER  
CONTAINS SQL  
BEGIN  
  DECLARE value INTEGER;  
  SET value = 0;  
  SELECT current_value INTO value  
  FROM sequence  
  WHERE name = seq_name;  
  RETURN value;  
END$  
DELIMITER ;  


 


 测试一下结果:

 

 

 



mysql> SELECT currval('MovieSeq');  
+---------------------+  
| currval('MovieSeq') |  
+---------------------+  
|                   3 |  
+---------------------+  
1 row in set (0.00 sec)  
mysql> SELECT currval('x');  
+--------------+  
| currval('x') |  
+--------------+  
|            0 |  
+--------------+  
1 row in set, 1 warning (0.00 sec)  
mysql> show warnings;  
+---------+------+------------------+  
| Level   | Code | Message          |  
+---------+------+------------------+  
| Warning | 1329 | No data to FETCH |  
+---------+------+------------------+  
1 row in set (0.00 sec)  


 


 nextval

 

 

//获取下一个数值..先在sequence里面调用update当前最大数值+1然后再调用currval获得当前数值

 


 

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

 mysql> select nextval('MovieSeq'); 

 

+---------------------+  
| nextval('MovieSeq') |  
+---------------------+  
|                  15 |  
+---------------------+  
1 row in set (0.09 sec)  
  
mysql> select nextval('MovieSeq');  
+---------------------+  
| nextval('MovieSeq') |  
+---------------------+  
|                  20 |  
+---------------------+  
1 row in set (0.01 sec)  
  
mysql> select nextval('MovieSeq');  
+---------------------+  
| nextval('MovieSeq') |  
+---------------------+  
|                  25 |  
+---------------------+  
1 row in set (0.00 sec)  


 


 setval 

 

 

 

DROP FUNCTION IF EXISTS setval;  
DELIMITER $  
CREATE FUNCTION setval (seq_name VARCHAR(50), value INTEGER)  
RETURNS INTEGER  
CONTAINS SQL  
BEGIN  
   UPDATE sequence  
   SET          current_value = value  
   WHERE name = seq_name;  
   RETURN currval(seq_name);  
END$  
DELIMITER ;  

 mysql> select setval('MovieSeq',150); 

 

+------------------------+  
| setval('MovieSeq',150) |  
+------------------------+  
|                    150 |  
+------------------------+  
1 row in set (0.06 sec)  
  
mysql> select curval('MovieSeq');  
+---------------------+  
| currval('MovieSeq') |  
+---------------------+  
|                 150 |  
+---------------------+  
1 row in set (0.00 sec)  
  
mysql> select nextval('MovieSeq');  
+---------------------+  
| nextval('MovieSeq') |  
+---------------------+  
|                 155 |  
+---------------------+  
1 row in set (0.00 sec) 


 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值