zig*_*ggy 14 mysql sql database oracle spring
我需要能够生成运行查询,该查询将返回下表中的下一个ID值:
CREATE TABLE animals (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
)
Run Code Online (Sandbox Code Playgroud)
在Oracle中,您可以在序列上调用NEXTVAL,它会为您提供下一个序列(注意:无需在表上插入).
谷歌搜索后,我发现你可以使用以下查询找到auto_increment的当前值:
SELECT Auto_increment
FROM information_schema.tables
WHERE table_name='animals';
Run Code Online (Sandbox Code Playgroud)
问题是我希望每次查询值时增加值.在Oracle中,当您调用nextval时,即使您没有在表中插入行,序列的值也会增加.
有什么方法可以修改上面的查询,以便返回的值总是与上次调用查询时不同?即每次检查时Auto_increment都会递增,当在查询中使用时,它将使用新值.
我正在使用Spring JDBCTemplate,所以如果可以在一个查询中完成,那就更好了.
小智 12
http://docs.oracle.com/cd/E17952_01/refman-5.5-en/example-auto-increment.html
3.6.9.使用AUTO_INCREMENT
AUTO_INCREMENT属性可用于为新行生成唯一标识:
Run Code Online (Sandbox Code Playgroud)CREATE TABLE animals ( id MEDIUMINT NOT NULL AUTO_INCREMENT, name CHAR(30) NOT NULL, PRIMARY KEY (id) ); INSERT INTO animals (name) VALUES ('dog'),('cat'),('penguin'), ('lax'),('whale'),('ostrich'); SELECT * FROM animals; Which returns: +----+---------+ | id | name | +----+---------+ | 1 | dog | | 2 | cat | | 3 | penguin | | 4 | lax | | 5 | whale | | 6 | ostrich | +----+---------+
没有为AUTO_INCREMENT列指定值,因此MySQL会自动分配序列号.您还可以显式为列分配NULL或0以生成序列号.
您可以使用LAST_INSERT_ID()SQL函数或mysql_insert_id()C API函数检索最新的AUTO_INCREMENT值.这些函数是特定于连接的,因此它们的返回值不受另一个也执行插入的连接的影响.
使用AUTO_INCREMENT列的最小整数数据类型,该列足够大以容纳您将需要的最大序列值.当列达到数据类型的上限时,下一次生成序列号的尝试将失败.如果可能,请使用UNSIGNED属性以允许更大的范围.例如,如果使用TINYINT,则允许的最大序列号为127.对于TINYINT UNSIGNED,最大值为255.请参见第11.2.1节"整数类型(精确值) - INTEGER,INT,SMALLINT,TINYINT,MEDIUMINT,BIGINT "对于所有整数类型的范围.
注意对于多行插入,LAST_INSERT_ID()和mysql_insert_id()实际上从第一个插入的行返回AUTO_INCREMENT键.这使得多行插入可以在复制设置中的其他服务器上正确再现.
如果AUTO_INCREMENT列是多个索引的一部分,则MySQL使用以AUTO_INCREMENT列开头的索引(如果有)生成序列值.例如,如果animals表包含索引PRIMARY KEY(grp,id)和INDEX(id),则MySQL将忽略PRIMARY KEY以生成序列值.因此,该表将包含单个序列,而不是每个grp值的序列.
要以除1以外的AUTO_INCREMENT值开始,请使用CREATE TABLE或ALTER TABLE设置该值,如下所示:
mysql> ALTER TABLE tbl AUTO_INCREMENT = 100; InnoDB备注
对于InnoDB表,如果在INSERT语句序列的中间修改包含自动增量值的列,请务必小心.例如,如果使用UPDATE语句在自动增量列中放入一个新的较大值,则后续INSERT可能会遇到"重复条目"错误.如果执行DELETE后跟更多INSERT语句,或者执行COMMIT事务,而不是在UPDATE语句之后,则会测试是否已存在自动增量值.
MyISAM笔记
对于MyISAM表,可以在多列索引的辅助列上指定AUTO_INCREMENT.在这种情况下,AUTO_INCREMENT列的生成值计算为MAX(auto_increment_column)+ 1 WHERE prefix = given-prefix.当您想要将数据放入有序组时,这非常有用.
Run Code Online (Sandbox Code Playgroud)CREATE TABLE animals ( grp ENUM('fish','mammal','bird') NOT NULL, id MEDIUMINT NOT NULL AUTO_INCREMENT, name CHAR(30) NOT NULL, PRIMARY KEY (grp,id) ) ENGINE=MyISAM; INSERT INTO animals (grp,name) VALUES ('mammal','dog'),('mammal','cat'), ('bird','penguin'),('fish','lax'),('mammal','whale'), ('bird','ostrich'); SELECT * FROM animals ORDER BY grp,id; Which returns: +--------+----+---------+ | grp | id | name | +--------+----+---------+ | fish | 1 | lax | | mammal | 1 | dog | | mammal | 2 | cat | | mammal | 3 | whale | | bird | 1 | penguin | | bird | 2 | ostrich | +--------+----+---------+
在这种情况下(当AUTO_INCREMENT列是多列索引的一部分时),如果删除任何组中具有最大AUTO_INCREMENT值的行,则重用AUTO_INCREMENT值.即使对于MyISAM表也会发生这种情况,因为通常不会重复使用AUTO_INCREMENT值.
进一步阅读
有关AUTO_INCREMENT的更多信息,请访问:
如何将AUTO_INCREMENT属性分配给列:第13.1.17节"CREATE TABLE语法"和第13.1.7节"ALTER TABLE语法".
AUTO_INCREMENT的行为取决于NO_AUTO_VALUE_ON_ZERO SQL模式:第5.1.7节"服务器SQL模式".
如何使用LAST_INSERT_ID()函数查找包含最新AUTO_INCREMENT值的行:第12.14节"信息函数".
设置要使用的AUTO_INCREMENT值:第5.1.4节"服务器系统变量".
AUTO_INCREMENT和复制:第16.4.1.1节"复制和AUTO_INCREMENT".
与AUTO_INCREMENT(auto_increment_increment和auto_increment_offset)相关的服务器系统变量,可用于复制:第5.1.4节"服务器系统变量".
http://search.oracle.com/search/search?q=auto_increment&group=Documentation&x=0&y=0
使用InnoDB的这个示例演示了使用互锁查询实现自己的计数器的方法:
http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
你需要什么来创造一个差距?要保留ID?我宁愿"不惜一切代价"修复设计并更新其他模块而不是触及序列.
我不是只显式地增加序列,而是通过为每个id插入一个默认行(标记为无效)来分配并返回id.这种方法是一致和便携的.稍后,您可以使用匹配的序列值更新这些默认行,而不是使用显式序列值强制插入.这需要更多内存但没有锁.过期行上的垃圾收集可以在这里提供帮助.'insert或update'语句可以重新创建垃圾收集行,但我不会这样做.
您可以添加自己的 MySQL 函数 - 如http://www.microshell.com/database/mysql/emulating-nextval-function-to-get-sequence-in-mysql/ 所示- 允许您执行以下操作:
SELECT nextval('sq_my_sequence') as next_sequence;
Run Code Online (Sandbox Code Playgroud)