我以前通过执行类似以下的简单查询来获取Access中使用的下一个可用自动编号:
SELECT RecordNumber, Info
FROM myTABLE
WHERE 0 = 1
这样,我可以创建一个变量来保存currentRecord,它将使用与我在更新行时Access将要使用的相同的自动编号
示例
rs.AddNew
currentRecord = rs("RecordNumber")
rsInfo = "SomeFormData" & currentRecord
rs.Update
rs.Close
现在,此功能可用于MS Access,但在SQL Server 2005中,我没有找回新记录创建的身份。已正确插入“ SomeFormData”,SQL中的RecordNumber字段已由新的自动编号填充,但是我的变量中没有RecordNumber,我需要它来继续填写相关表格,从而将数据保存到相关表中并需要保存currentRecord号。
问题:在进行新插入时,是否有办法找回此唯一编号?
IDENT_CURRENT('tableName')
(包括单引号)返回给定表的标识的当前值。该值应该是表中最后使用的标识值。换句话说,除非表中已删除该行,否则该表中将具有该标识值的行。将在下一个INSERT
上分配的标识值将是IDENT_CURRENT('tableName') + IDENT_INCR('tableName')
。 不过,我不建议依赖此。如果您以此方式预先确定下一个标识值,那么您肯定会遇到这样的情况,即另一个进程在插入之前先实际获得了该ID,因此您的进程最终使用了错误的ID值。
最好先插入(即使您还没有全部数据,然后使用SCOPE_IDENTITY()
来获取分配的实际ID。
您可能想知道为什么SCOPE_IDENTITY()
比IDENT_CURRENT('tableName')
好。顾名思义,前者将为您提供在当前范围内分配的最新身份值(您的批次,存储的过程,无论如何),而后者将为您提供任何人在表上分配的最新身份。即使您可能在'IDENT_CURRENT
之后立即调用INSERT
,也有可能在两者之间出现其他人的INSERT
,并且IDENT_CURRENT
将为您提供
their插入而不是您的插入产生的标识值,而SCOPE_IDENTITY
总是会给您您的。
编辑:
还值得一提的是,SCOPE_IDENTITY()
比功能类似的@@IDENTITY
更受青睐。两者都返回当前批次中分配的最新标识值,而@@IDENTITY
受触发器内发生的插入操作的影响; SCOPE_IDENTITY()
不是。这里有一个存储过程的例子
IF object_id('spOrganizationAdd') IS NOT NULL
DROP PROCEDURE spOrganizationAdd;
GO
CREATE PROCEDURE dbo.spOrganizationAdd
@OrganizationName VARCHAR(50),
@ReturnIdentityValue INT OUTPUT
AS
BEGIN
DECLARE @TempOrganizationIdentity TABLE (TempOrganizationID INT)
INSERT INTO Organization (OrganizationName)
OUTPUT INSERTED.OrganizationID INTO @TempOrganizationIdentity
VALUES (@OrganizationName)
SELECT @ReturnIdentityValue = (SElECT TempOrganizationID FROM @TempOrganizationIdentity)
END
GO
这里是调用它的C#代码的示例...请注意ParameterDirection.Output
:
public static int AddOrganization(Organization oOrganization) { int iRetVal = 0; using (SqlConnection conn = Connection.GetConnection()) { using (SqlCommand cmd = new SqlCommand("spOrganizationAdd", conn)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@OrganizationName", oOrganization.OrganizationName); cmd.Parameters.Add("@ReturnIdentityValue", SqlDbType.Int).Direction = ParameterDirection.Output; conn.Open(); cmd.ExecuteNonQuery(); iRetVal = Convert.ToInt32(cmd.Parameters["@ReturnIdentityValue"].Value); } } return iRetVal; }
类示例
public class Organization { public Organization() { } public Organization(int organizationID) { OrganizationID = organizationID; } public int OrganizationID { get; set; } public string OrganizationName { get; set; } public string Display() { return OrganizationID.ToString() + " " + OrganizationName; } }