VB.NET SQL 最后插入的 ID

9
我正在使用VB.NET和Access数据库,我插入了一些值,但是接下来我需要获取最后插入的ID(自动编号),并将其插入到相关表中。
我尝试过@@IDENTITY和MAX(column),但@@IDENTITY返回零,而MAX不太可靠(有时在插入数据之前获取ID会很慢,因此获取的ID是插入的那个)。
Dim insertSql = datalayer.getDataTable((String.Format("INSERT INTO users (username) VALUES ({0})", username)))

Dim newID = datalayer.getDataTable((String.Format("SELECT @@IDENTITY FROM users")))


Dim con As OleDbConnection = getConnection()
con.Open()
Dim sqlCommand As OleDbCommand = New OleDbCommand(String.Format(insertSql), con)
sqlCommand.ExecuteNonQuery()

这是由两个函数完成的,因此上述代码可能看起来很混乱,但那只是从两个函数中获取的。这两个语句都会被执行,但我只展示了一个作为例子。

是否有替代@@IDENTITY和MAX的方法?因为我似乎看不出我在@@IDENTITY方面错了哪里?

感谢任何建议 :)


请查看我的最后一次编辑,关于Access不支持在一个命令中执行多个语句。您能否确认它是否实际可行,或者您采取了其他方法? - Pauli Østerø
2个回答

10

在插入操作和执行SELECT @@IDENTITY语句时,一定要在同一个连接(和事务)上执行。如果你的getDataTable()方法为每次调用创建了新连接,那么这就是它无法工作的原因。

更新

另一种更可取的方法是将这两个语句合并为一个。

sql = "INSERT INTO...;SELECT @@IDENTITY..." 
Dim id = sqlCommand.ExecuteScalar(sql)

再次更新

看起来你不能像这样在 MS Access 数据库中执行多个函数:运行多个SQL语句.


嗨,是的,它不会创建新的连接。如果我只是在窗体加载时建立一个到数据库的连接,那么对于插入、更新等操作,这样做是否可行?谢谢。 - Elliott
+1 为提供了一种使用 ExecuteScalar 方法的方式,将两个 SQL 语句封装起来。这个我从来没有想过。=) - Will Marcouiller
我非常怀疑你能够在Access中同时执行两个语句。 - Fionnuala
@Remou 看起来你是对的 https://dev59.com/GEfRa4cB1Zd3GeqP70kf - Pauli Østerø
在我看来,这个答案应该将第一段之后的所有内容都编辑掉,因为其余部分都不适用。 - David-W-Fenton
另外,随着A2010附带的ACE现在支持可以像触发器一样运行的表级数据宏,我担心在主插入触发器触发另一个具有自动编号字段的表的插入时,SELECT @@IDENTITY可能会返回不正确的结果。需要的是SQL Server的Scope_Identity()的等效物,但据我所知,在A2010/ACE中不存在。我已经在各个地方询问了这个问题,但似乎没有人知道答案。 - David-W-Fenton

0
您可以简单地使用以下代码。 我假设您使用了SQLDataSource并且事件是:

Protected Sub SqlDataSource1_Inserted(sender As Object, e As SqlDataSourceStatusEventArgs) Handles SqlDataSource1.Inserted
Dim query As String = "SELECT @@IDENTITY"
Dim cmd As New OleDbCommand(query, CType(e.Command.Connection,   OleDbConnection))
Dim newid As Integer = cmd.ExecuteScalar()
l1.Text = newid
End Sub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接