如何在sql中获取下一个自动增量值

Posted

技术标签:

【中文标题】如何在sql中获取下一个自动增量值【英文标题】:how to get the next autoincrement value in sql 【发布时间】:2012-07-13 05:17:04 【问题描述】:

我正在用 c#.and 使用 sql 数据库创建一个 winform 应用程序。

我有一张表employee_master,其中有Id, name, addressphone no 之类的列。 Id 是自动递增的,所有其他数据类型都是 varchar

我正在使用此代码来获取下一个自动增量值:

string s = "select max(id) as Id from Employee_Master";
SqlCommand cmd = new SqlCommand(s, obj.con);
SqlDataReader dr = cmd.ExecuteReader();
dr.Read();
int i = Convert.ToInt16(dr["Id"].ToString());
txtId.Text = (i + 1).ToString();

我正在一个文本框上显示。

但是当表中的最后一行被删除时,我仍然得到最近在文本框中删除的值

我应该如何获得下一个自增值?

【问题讨论】:

为什么要这样做?您无法在多用户环境中向用户显示下一个 ID,因为任何人都可以获取它... 什么样的SQL数据库?品种很多 没有可靠的方法来确定 SQL Server 中自动增量 (IDENTITY) 列的下一个值。 直到INSERT 实际发生后,该值才得到保证。 为什么在你决定插入之前需要这个值?你打算用它做什么,为什么?你为什么要向用户展示它?最终用户不应该知道或关心分配了哪些身份值。我真的必须提醒您不要接受您已接受的 IDENT_CURRENT“解决方案”,并鼓励您使用多个并发用户和回滚进行测试。 @agleno 我认为这有助于提出手头的实际问题,防止浪费时间解决甚至可能不存在的问题(有助于澄清)。 【参考方案1】:

max(id) 将获得列表 pf employee_master 中的最大数量

例如id = 10, 20, 100 所以 max 会给你 100

但是当你删除记录时,它一定不是 100

所以你仍然可以得到 100 的回报

我说这可能是问题的一个重要原因,因为您没有在查询中使用 order by id

【讨论】:

【参考方案2】:

如果您使用的是 Microsoft SQL Server。使用此语句获取表的当前标识值。然后添加您在设计表格时指定的种子值,如果您想获得下一个 id。

SELECT IDENT_CURRENT(<TableName>)

【讨论】:

但同样适用:没有可靠的方法来确定IDENTITY 列的下一个值。是的 - IDENT_CURRENT 加上定义的增量值是最有可能 值 - 但它不是 100% 确定实际上是真正的下一个值。您只是无法确定下一个值 - 直到 INSERT 发生....【参考方案3】:

从 SQLServer 获取下一个自增值:

这将获取当前的自动增量值。

SELECT IDENT_CURRENT('table_name');

下一个自增值。

SELECT IDENT_CURRENT('table_name')+1; 

--------> 即使您添加一行然后删除它,这也会起作用,因为 IDENT_CURRENT 返回为任何会话和任何范围内的特定表生成的最后一个标识值。

【讨论】:

这显然不是真的 - IDENTITY 的增量可能不同于 1 !事实是:您无法获取 SQL Server 中 IDENTITY 列的下一个值 - 没有办法这样做。这些值仅在 INSERT 发生时设置 - 而不是之前。 @patel.milanb:IDENTITY 的增量值可能是 5 - 所以您的下一个值将是 1515(并且 NOT 1511 !) - 而且:如果下一个插入被回滚,一个值(如 1515)可能会“丢失” - real 下一个值最终为 1520。只需将 +1 添加到 @ 987654326@ 充其量只是一个 GUESS ..... 任何小问题,服务器都会跳到下一个数字..如果有几个问题,它会跳几个数字; sereral 因此是不可预测的,所以只做)+1 是错误的 您还会遇到并发问题。如果两个用户同时尝试添加员工,您将派生相同的“下一个 ID”,但第二次保存将收到不同的 ID。 我们也认为这是一个坏主意。即使获取下一个值的方法确实有效,也存在许多问题。我们遇到了大容量问题...在检索下一个值并插入记录时,另一个用户正在创建记录并且值会混淆。就像其他人说的那样,这不是一个好方法。【参考方案4】:

当您从表中删除一行时,下一个数字将保持不变,因为它不会以任何方式递减。

因此,如果您有 100 行并删除了第 100 行。您将有 99 行,但下一个数字仍将是 101。

【讨论】:

【参考方案5】:
select isnull((max(AddressID)+1),1) from AddressDetails

【讨论】:

【参考方案6】:

试试这个:

SELECT IDENT_CURRENT('tbl_name') + IDENT_INCR('tbl_name');

【讨论】:

正如 marc_s 指出的那样,不能保证下一个自动递增的身份。因此,如果插入到两个表中,其中一个表有一个外键(显式或其他)到另一个(相互依赖),那么只需将两个操作都包含在同一个事务中(以防止任何竞争条件)。【参考方案7】:

对于 MS SQL 2005 及更高版本:

Select Cast(IsNULL(last_value,seed_value) As Int) + Cast(increment_value As Int) As NextID
From sys.identity_columns
WHERE NAME = <Table_Name>

【讨论】:

【参考方案8】:

想一想,如果您想要的是您在已打开的连接上插入的最后一个自动编号,请尝试使用:

SELECT @@IDENTITY FROM...

来自那个连接。这是跟踪给定连接上刚刚发生的事情并避免与其他连接竞争的最佳方式。获得最大身份通常是不可行的。

【讨论】:

【参考方案9】:
 SqlConnection con = new SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=databasename;User ID=sa;Password=123");
 con.Open();
 SqlCommand cmd = new SqlCommand("SELECT TOP(1) UID FROM InvoiceDetails ORDER BY 1 DESC", con);

 SqlDataReader reader = cmd.ExecuteReader();

 //won't need a while since it will only retrieve one row
 while (reader.Read())
 
     string data = reader["UID"].ToString();
     //txtuniqueno.Text = data;
     //here is your data
     //cal();
     //txtuniqueno.Text = data.ToString();
     int i = Int32.Parse(data);
     i++;
     txtuid.Text = i.ToString();
  

【讨论】:

【参考方案10】:

对我来说,最好的答案是:

dbcc checkident(table_name)

您将看到两个值(可能相同) 当前标识值,当前列值

【讨论】:

以上是关于如何在sql中获取下一个自动增量值的主要内容,如果未能解决你的问题,请参考以下文章

如何在单个查询(sql server)中插入1条记录后检索自动增量值

如何获取表中的最后一个自动增量值? VB.NET

如何使用 PDO 在 MySQL 中找到下一个自动增量值? [复制]

如何检索 MS-Access 中的最后一个自动增量值,例如 Sql Server 中的 @@Identity

如何通过 SQL 插入增量值

在 Scala 中使用 Slick 库获取自动增量值