设为首页 收藏本站
查看: 626|回复: 0

[经验分享] 在SQLServer/MySQL数据库中如何取得刚插入的标识值

[复制链接]

尚未签到

发表于 2016-10-23 10:52:34 | 显示全部楼层 |阅读模式
  在SQLServer/MySQL数据库中如何取得刚插入的标识值
  在SQLServer数据库中
  数据库实际应用中,我们往往需要得到刚刚插入 的标志值来往相关表中写入数据。但我们平常得到的真的是我们需要的那个值么?
(1)、有时我们会使用 SELECT @@Identity 来获得我们刚刚插入的值,比如下面的代码
  代码一:
use tempdb
if exists (select * from sys.objects where object_id = object_id(N'[test1]') and type in (N'u'))
drop table [test1]
go
create table test1
(
id int identity(1,1),
content nvarchar(100)
)
insert into test1 (content) values ('solorez')
select @@identity
  乐观情况下,这样做是没问题的,但如果我们如果先运行下面的代码二创建一个触发器、再运行代码三:
  代码二:
create table test2
(
id int identity(100,1),
content nvarchar(100)
)
  create trigger tri_test1_identitytest_I
on test1 after insert
as
begin
insert into test2
select content from inserted
end
  代码三:
insert into test1 (content) values ('solorez2')
select @@identity

我们可以看到,此时得到的标识值已经是100多了,很明显,这是表test2的生成的标识值,已经不是我们想要的 了。
我们可以看看@@identity的定义:Identity
原来,@@identity返回的是当前事务最后插入的标识值,因为在Insert Test1表执行后,紧接着触发了触发器又Insert Test2表,所以,这时候@@identity的值就是表test2的生成的标识值。


  (2)、这 时我们或许会用下面的方法:
  代码四:
insert into test1 (content) values ('solorez3')
SELECT IDENT_CURRENT('test1')
  看来结果还比较正确,但如果我们在多次运行代码四的同时运行下面的代码五:
  代码五:
insert into test1 (content) values ('solorez3')
  waitfor delay '00:00:20'
SELECT IDENT_CURRENT('test1')

结果又 不是我们想要的了!
再看看IDENT_CURRENT(Tablename) 的定义:IDENT_CURRENT(Tablename)
是 返回指定表的最后标识值。

  (3)、到这里,是该亮出答案的时候了,我们可以使用下面的代码:
  代码六:
insert into test1 (content) values ('solorez3')
SELECT scope_identity()
  这时,我们无论是添加触发器还是运行并行插入,得到的始终是当前事务的标识值。
  scope_identity()的定义:scope_identity()返回为当前会话和当前作用域中的某个表生成的最新标识值
  
  三个函数的区别:
  IDENT_CURRENT 返回为某个会话和用域中的指定表生成的最新标识值。
  @@IDENTITY 返回为跨所有作用域的当前会话中的某个表生成的最新标识值。
  SCOPE_IDENTITY 返回为当前会话和当前作用域中的某个表生成的最新标识值。
  
  
  在MySQL数据库中
  一般情况下获取刚插入的数据的id,使用select max(id) from table 是可以的。
  但在多线程情况下,就不行了。
  下面介绍三种方法
  (1) getGeneratedKeys()方法:
  (2)LAST_INSERT_ID:
  LAST_INSERT_ID 是与table无关的,如果向表a插入数据后,再向表b插入数据,LAST_INSERT_ID会改变。
  在多用户交替插入数据的情况下max(id)显然不能用。
  这就该使用LAST_INSERT_ID了,因为LAST_INSERT_ID是基于Connection的,只要每个线程都使用独立的Connection对象,LAST_INSERT_ID函数将返回该Connection对AUTO_INCREMENT列最新的insert or update*作生成的第一个record的ID。这个值不能被其它客户端(Connection)影响,保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁。
  可以用 SELECT LAST_INSERT_ID(); 查询LAST_INSERT_ID的值.
  使用单INSERT语句插入多条记录, LAST_INSERT_ID只返回插入的第一条记录产生的值.
  (3)select @@IDENTITY:
  String sql=”select @@IDENTITY”;
  @@identity是表示的是最近一次向具有identity属性(即自增列)的表插入数据时对应的自增列的值,是系统定义的全局变量。一般系统定义的全局变量都是以@@开头,用户自定义变量以@开头。比如有个表A,它的自增列是id,当向A表插入一行数据后,如果插入数据后自增列的值自动增加至101,则通过select @@identity得到的值就是101。使用@@identity的前提是在进行insert操作后,执行select @@identity的时候连接没有关闭,否则得到的将是NULL值。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-290191-1-1.html 上篇帖子: (转)MySQL的经典用法(三)----海量数据统计处理,模拟物化视图 下篇帖子: MySQL源码分析(4):InnoDB主要数据结构及调用流程(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表