- Rongsen.Com.Cn 版权所有 2008-2010 京ICP备08007000号 京公海网安备11010802026356号 朝阳网安编号:110105199号
- 北京黑客防线网安工作室-黑客防线网安服务器维护基地为您提供专业的
服务器维护
,企业网站维护
,网站维护
服务 - (建议采用1024×768分辨率,以达到最佳视觉效果) Powered by 黑客防线网安 ©2009-2010 www.rongsen.com.cn
作者:黑客防线网安SQL维护基地 来源:黑客防线网安SQL维护基地 浏览次数:0 |
过去的几个月里,我有幸面试了众多应聘DBA和DB开发岗位的求职者。我们希望开发人员能够创建存储过程,编写合理的复杂SQL语句,以及触发器。我喜欢问这些求职者一个问题:
“假设我们使用SQL Server2000进行开发。现在我需要传递给存储过程两个变量:firstname和lastname。存储过程负责向名字为TEST的表插入这两个变量,其中TEST表有两个字段,名字就叫firstname和lastname。TEST表的主键是一个自增长类型的字段,名字叫ContactID。问题是我如何获取插入的那条数据的主键值。”
让我们想一下答案是什么。你是否知道如何创建存储过程,获取数值并返回给调用的应用程序?
有人会直接问我-这个问题重要吗?对于我来说,我问这个问题的目的是为了测试求职者是否有求解非常规需求的能力。设想一下标准的订单/订单明细表应用场景--你是否知道如何不知道订单主键的情况下插入订单的详细信息?当你因为没有使用主键时,可能会带来锁问题。这时,自增长字段加入是常用的一个手段。但是使用@@Identity来获取插入数据的标识,有可能会带来问题,比如在触发器内使用就会发生问题。这并不是一个可以给出唯一答案的问题,但是这个问题可以让我们对处理类似表的问题,来展开讨论。
我收到了很多不同的回答,但是绝大多数并非最优。几乎每个人都知道如何插入数据、如何返回值,但是几乎每个人都在获取自增长字段取值上回答得不是很好。
错误回答 #1 - Select max(contactid) from Test.
因为你无法避免别人也同时在插入数据,因此这个回答是错误的。当然,你可以通过提升隔离级别来达到目的,但是这将会大幅降低并发性能,因此不好。
错误回答 #2 - Select top 1 contactid from test order by contactid desc.
错误的原因和回答#1一样。
错误回答 #3 - 通过插入的数据来组合成一个唯一的标识,从而获得自增长字段的值。如果插入的数据确实组合起来是唯一的,能达到目的,但是如果不唯一,怎么办呢?因此这也不是好办法。
错误回答 #4 - 这个回答很接近正解了。这些回答者建议使用@@Identity,自然这是可以的 (小心,要知道如何正确使用@@Identity), 但是当我问他们关于@@Identity的相关技术细节时,我收到最多的答案如下:
- 对不起,我不是很清楚。
- 你应该尽快获取@@Identity的值,因为其它人的对表插入数据,也会改变这个值。
- 是的,获取最后一个identity值,在大多数情况下是可行的,但是如果在TEST表上有触发器,这个触发器会自动向别的表插入数据,如果那个表也同样有一个自增长字段,那么错误就会发生。此时,你获取的@@Identity取值是那个表的identity取值(注意:这个回答正确地描述了 @@Identity的行为)。
正确答案 - 因为我们使用的是SQL Server 2000,因此使用Scope_Identity() , 如果用的是SQL Server 7,那么只有只用@@Identity,并且以output参数方式传递(return值一般是用来作为错误代码用)。使用@@Identity意味着将来也许会发生错误,例如审核时使用自增长字段。
现在我们来做一系列的试验来验证:
create database IdentityTest
use identitytest
create table TEST (ContactID int not null identity (1, 1), firstname varchar(100) null, lastname varchar(100) null)
insert into TEST Default Values
select @@Identity
运行后会返回1。如果在此运行,则返回 2。
insert into TEST Default Values
select Scope_Identity()
运行后返回 3。
我要申请本站:N点 | 黑客防线官网 | |
专业服务器维护及网站维护手工安全搭建环境,网站安全加固服务。黑客防线网安服务器维护基地招商进行中!QQ:29769479 |