转自:http://foolraty.iteye.com/blog/777215
http://www.blogjava.net/Skynet/archive/2011/03/23/301847.html
http://sulong.me/2011/11/14/spring_mysql_sequence
MySQL This function has none of DETERMINISTIC, NO SQL...错误1418 的原因分析及解决方法
http://blog.csdn.net/ty_soft/article/details/6940190
一、 单独的数据表+函数:
如果你不想使用mysql的自动递增,但又想实现主键序列号的功能,可以使用下面的方法,通过函数用一张表去维护生成多个表的序列号,简单又实用
1.创建生成多个表的序列号的数据维护表
CREATE TABLE seq (
name varchar(20) NOT NULL,
val int(10) UNSIGNED NOT NULL,
PRIMARY KEY (name)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
2.插入几条初始化数据
INSERT INTO seq VALUES('one',100);
INSERT INTO seq VALUES('two',1000);
3.创建函数以生成序列号
CREATE FUNCTION seq(seq_name char (20)) returns int
begin
UPDATE seq SET val=last_insert_id(val+1) WHERE name=seq_name;
RETURN last_insert_id();
end
4.测试
-
mysql> SELECT seq('one'),seq('two'),seq('one'),seq('one');
-
+------------+------------+------------+------------+
-
| seq('one') | seq('two') | seq('one') | seq('one') |
-
+------------+------------+------------+------------+
-
| 102 | 1002 | 103 | 104 |
-
+------------+------------+------------+------------+
-
1 row IN SET (0.00 sec)
二、触发器
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)
三、下面就是另外一个的实现方案:
原理是创建一个专门记录序列的表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
- +------------------------+
- | 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)
相关推荐
在MySQL中,自增序列(Sequence)是一种常用于生成唯一标识符的数据结构,尤其是在Oracle数据库中广泛使用。然而,MySQL自身并不直接支持Sequence,但可以通过创建表和存储过程来模拟这个功能。本教程将详细解释如何...
例如,MySQL通过`autoincrement`实现自增,Oracle则使用序列。但这些方法在分表后不再适用,因此需要寻找新的解决方案。 2. 解决方案对比 - 数据库表维护:在特定数据库中维护一个自增ID表,每次需要ID时加锁更新,...
然后在插入数据时,可以使用`NEXTVAL`函数获取序列的下一个值: ```sql INSERT INTO your_table (primary_key_column) VALUES (SEQ_PRIMARY_KEY.NEXTVAL); ``` 2. 使用触发器(Triggers): 触发器是基于数据库...
4. 使用序列`seque_id`创建一个触发器`tri_borrow`,使得借阅表中的借阅流水号字段在插入时自动递增。 5. 修改借书存储过程`p_borrow`,简化插入操作。 6. 建立借书存储过程的触发器,确保在借书时同步更新图书状态...
在MySQL中,序列是一种特殊的数据类型,常用于生成唯一的标识符,类似于其他数据库系统中的序列或自增字段。然而,MySQL本身并不直接支持序列,所以开发者通常需要借助触发器或存储过程来实现类似的功能。`mysql-...
identity是一种使用SQL Server和MySQL的自增字段生成主键的策略。这种策略不能用于Oracle,因为Oracle不支持自增字段。这种策略适用于需要高性能的场景。 select select是一种使用触发器生成主键的策略。这种策略...
在本文中,我们探讨了如何使用MySQL数据库管理系统来创建一个序列表,并利用触发器自动为新插入的记录生成序列号。这个操作涉及到几个重要的知识点:创建表、设置触发器以及数据插入。 首先,我们来看如何创建一个...
要注意的是,Oracle的自增字段(通过序列和触发器实现)在MySQL中需要改为直接使用字段的自动递增特性,这个字段必须是主键且不能有默认值。 二、触发器的移植 MySQL从6.0版本开始支持触发器,但与Oracle的触发器...
- 如果使用MySQL数据库,则推荐使用自增`INT`类型作为主键;而Oracle数据库建议使用`UUID`作为主键。 - 对于金额字段,若需要进行计算操作,则使用`NUMBER`类型存储整数,计算完毕后再将结果除以100以获取实际数值。...
Oracle提供了丰富的窗口函数,而在MySQL中,可以使用`Window Function`来实现类似功能,但具体语法有所区别。例如,Oracle的`ROW_NUMBER()`在MySQL中可以使用`ROW_NUMBER() OVER()`,但这里未涉及具体的窗口函数...
本课件主要介绍了MySQL数据库编程的基础知识,涵盖了MySQL语言结构、存储过程、存储函数、触发器等内容。通过学习本课件,学生可以掌握MySQL数据库编程的基本技能,能够独立完成数据库编程任务。 知识点1:MySQL...
例如,Oracle支持PL/SQL,这是一种强大的过程式编程语言,而MySQL则使用存储过程和触发器,语法结构略有不同。在函数转换过程中,如需将Oracle的`TO_CHAR()`用于日期格式化,在MySQL中应使用`DATE_FORMAT()`;Oracle...
在MySQL中,由于不支持直接创建序列,通常会采用其他方法来实现类似的功能,比如通过触发器或者表中的自增字段来实现。但在Oracle中,可以轻松地创建序列并使用它来自动生成唯一值。 例如,在Oracle中可以通过以下...
### MySQL触发器 触发器是一种特殊的存储过程,它会在满足特定条件时自动执行。触发器可以用来实现复杂的数据库相关功能。 #### 触发器命令 ```sql DELIMITER // CREATE TRIGGER trigger_name { BEFORE | AFTER }...
如果需要连续的序列,可能需要使用其他策略,如触发器或存储过程来维护。 - AUTO_INCREMENT 值可以在多个会话中同时增加,这意味着如果你有并发插入,可能会产生非连续的序列号。 - 当表包含 AUTO_INCREMENT 列且...
例如,Oracle的序列(Sequence)在MySQL中没有直接对应,可能需要创建自增ID或使用UUID。Oracle的游标、%TYPE、PL/SQL包等特性在MySQL中也有不同的实现方式。 在进行迁移时,务必注意不要影响源数据库的正常运行,...
MySQL是一种广泛使用的开源关系型数据库管理系统(RDBMS),以其高效、稳定和易于管理而受到全球开发者的青睐。本手册旨在帮助读者深入理解和掌握MySQL的核心概念和技术。 一、MySQL基础 1. 数据库与表:MySQL中的...
- Oracle的`NEXTVAL`函数在MySQL中可通过自定义函数或`LAST_INSERT_ID()`实现类似功能。 4. **翻页查询**: - MySQL使用`LIMIT`关键字进行分页,如`LIMIT m, n`,从第m+1条开始取n条数据。 5. **函数转换**: -...
MySQL - 使用序列或触发器 MySQL中没有内置的类似`IDENT_CURRENT()`和`IDENT_INCR()`的函数,但可以通过其他方式实现相同的目标: - **使用序列**:虽然MySQL本身没有内置的序列支持,但可以通过创建存储过程或者...
Oracle没有内置的自动增长类型,但可以通过创建序列和触发器来实现类似功能。 4. **翻页查询**: - MySQL的分页查询使用`LIMIT`关键字,如 `SELECT * FROM table LIMIT m, n`,Oracle则通常使用`ROWNUM`配合子查询...