ASP FAQ # Chinese [1]
http://www.aspfaq.com/show.asp?id=2174
如何获取数据表中最新插入的记录的 ID 编号?
SQL Server 数据库
SQL Server 2000 中提供了若干可以取代 @@IDENTITY 的新函数。这些函数不是全局性的,这比 @@IDENTITY 要好。当插入新记录后,你可以执行:
PRINT IDENT_CURRENT('table')
这行语句将返回最近在名为“table”的表中添加的记录的 ID 编号,不管“table”是否真的被创建。
另一个方法是:
PRINT SCOPE_IDENTITY()
这将返回当前的存储过程,触发器等等所创建的新记录的 ID 编号。
如果你使用的是 SQL Server 的旧版本,那么取得最新 ID 号的最佳办法,是用单独一个存储过程来完成新纪录插入和 ID 的获取。例如:
CREATE PROCEDURE myProc
@param1 INT
AS
BEGIN
SET NOCOUNT ON
INSERT INTO someTable
(
intField
)
VALUES
(
@param1
)
SET NOCOUNT OFF
SELECT NEWID = @@IDENTITY
END
然后在 ASP 代码中类似这样地调用:
<%
fakeValue = 5
set conn = Server.CreateObject("ADODB.Connection")
conn.open "<conn string>"
set rs = conn.execute("EXEC myProc @param1=" & fakeValue)
response.write "New ID was " & rs(0)
rs.close: set rs = nothing
conn.close: set conn = nothing
%>
如果你使用的是 SQL Server 2000,那么只需将上面存储过程中的
SELECT NEWID = @@IDENTITY
替换为
SELECT NEWID = SCOPE_IDENTITY()
即可。
@@IDENTITY 的全局特性带来的一个问题是,如果你执行了一个 INSERT 操作,而被操作的表有一个响应 INSERT 的触发器,这个触发器又执行了对另一个表的 INSERT 操作(并且在那个表产生了新的记录 ID 号),那么 @@IDENTITY 返回的将是后面产生的这个 ID 号。在 SQL Server 7.0 中,这个问题令人头疼。这里给你一个解决办法,不过,你可能得为此修改大量的代码。
CREATE TRIGGER triggerInsert_tablename ON tablename FOR INSERT AS
BEGIN
SELECT @@IDENTITY
-- rest of trigger's logic...
END
Access
新版的 Jet/OLEDB 数据源现在也支持 @@IDENTITY 了,参见 KB #232144。(就我的试验,比较麻烦,并且限制很多)
使用 Access 时,要取得最新 ID 你应该会用下面这样的代码:
<%
fakeValue = 5
set conn = Server.CreateObject("ADODB.Connection")
conn.open "<conn string>"
conn.execute "Insert into someTable(intField) values(" & fakeValue & ")"
set rs = conn.execute("select MAX(ID) from someTable")
response.write "New ID was " & rs(0)
rs.close: set rs = nothing
conn.close: set conn = nothing
%>
这里说“应该”,是因为可能会出现两个几乎同时进行的插入操作,如此便可能返回错误的 ID 号。当然,坦白地讲,对于这种可能出现“同时插入操作”的繁忙应用场景,你应当考虑使用 SQL Server 作为数据库……(ref)然而若要坚持使用 Access 并希望避免上述问题,你可以使用带有类型为 adOpenKeyset 的游标的 Recordset 对象(这是使用 Recordset 代替 SQL 语句的极罕见场景之一)。
<%
fakeValue = 5
set conn = Server.CreateObject("ADODB.Connection")
conn.open "<conn string>"
set rs = Server.CreateObject("ADODB.Recordset")
rs.open "select [intField] from someTable where 1=0", conn, 1, 3
rs.AddNew
rs("intField") = fakeValue
rs.update
response.write "New ID was " & rs("id")
rs.close: set rs = nothing
conn.close: set conn = nothing
%>
这里还提供更多信息。