【问题标题】:VB Get Autonum valuesVB 获取 Autonum 值
【发布时间】:2020-07-14 00:46:03
【问题描述】:

我使用下面的第一个“Using”语句在名为“Archives”的表中插入一行。该表有一个主键,它是 Access db 中的一个自动编号。我使用第二个 Using 语句检索 autonum 字段的值,通过我刚刚输入的参数进行搜索。虽然这工作得很好,但它看起来很丑。有没有办法在插入后将 autonum 字段返回给我? (顺便说一句 - 我已经从这两个语句之间删除了一些代码,所以如果它看起来有点奇怪,那可能就是原因。

    Using myConn As New OleDbConnection(strConnectionString),
        myInsertCommand As New OleDbCommand("INSERT INTO Archives (ArchUserName, ArchUserDomain, ArchDate, ArchRoot, ArchStatus) 
        VALUES (@strArchUser, @strArchUserDomain, @dteArchDate, @strArchRoot, @strArchStatus);", myConn)
            myInsertCommand.Parameters.Add("@strArchUser", OleDbType.VarChar, 100).Value = strArchUser
            myInsertCommand.Parameters.Add("@strArchDomain", OleDbType.VarChar, 100).Value = strArchDomain
            myInsertCommand.Parameters.Add("@dteArchDate", OleDbType.Date, 20).Value = dteArchDate
            myInsertCommand.Parameters.Add("@strArchRoot", OleDbType.VarChar, 255).Value = strArchRoot
            myInsertCommand.Parameters.Add("@strArchStatus", OleDbType.VarChar, 100).Value = strArchStatus
            myConn.Open()
            myInsertCommand.ExecuteNonQuery()
        End Using

       Dim sql As String = "SELECT ArchID
       FROM Archives
       WHERE ArchUserName = @ArchUserName
       AND ArchUserDomain = @ArchUserDomain
       AND ArchDate = @ArchDate
       AND ArchRoot = @ArchRoot"

        Using myConn As New OleDbConnection(strConnectionString),
              command As New OleDbCommand(sql, myConn)
            With command.Parameters
                .Add("@ArchUserName", OleDbType.VarChar, 50).Value = strArchUser
                .Add("@ArchUserDomain", OleDbType.VarChar, 50).Value = strArchDomain
                .Add("@ArchDate", OleDbType.Date).Value = dteArchDate
                .Add("@ArchRoot", OleDbType.VarChar, 50).Value = strArchRoot
            End With

            myConn.Open()
            strArchID = "Arch" & CStr(command.ExecuteScalar())
            strDirectoryName = "Archive" & CStr(command.ExecuteScalar())
            ReturnCode = 0
        End Using

【问题讨论】:

  • "SELECT @@Identity"。您可以保留ExecuteScalar()。有人可能会问为什么?
  • 您不应该调用ExecuteScalar 两次来获取值。显然两次都应该是相同的值,那么为什么要执行两次相同的查询呢?调用ExecuteScalar 一次,将结果分配给一个变量,然后多次使用该变量。切勿多次执行相同的复杂表达式,除非您每次都期望得到不同的结果。数据库查询是最复杂的表达式之一,因为它非常昂贵。
  • 另外,您不应该创建两个单独的连接。创建一个连接,打开它,执行INSERT语句,执行查询得到自动生成的ID,然后关闭连接。
  • 承认我只是通过企业库完成了这项工作,而不是直接的 ADO,但看不到它不起作用。将 SELECT SCOPE_IDENTITY() AS NewID 附加到插入命令的末尾,然后 ExecuteScaler() 将返回新创建记录的 id

标签: vb.net ms-access oledb


【解决方案1】:

在插入后立即在同一连接上使用@@Identity。

Private Function InsertArchiveRetrieveID(strArchUser As String, strArchDomain As String, dteArchDate As Date, strArchRoot As String, strArchStatus As String) As Integer
    Dim NewID As Integer
    Using myConn As New OleDbConnection(strConnectionString),
            myInsertCommand As New OleDbCommand("INSERT INTO Archives (ArchUserName, ArchUserDomain, ArchDate, ArchRoot, ArchStatus) 
                                                               VALUES (@strArchUser, @strArchUserDomain, @dteArchDate, @strArchRoot, @strArchStatus);", myConn)
        With myInsertCommand.Parameters
            .Add("@strArchUser", OleDbType.VarChar, 100).Value = strArchUser
            .Add("@strArchDomain", OleDbType.VarChar, 100).Value = strArchDomain
            .Add("@dteArchDate", OleDbType.Date, 20).Value = dteArchDate
            .Add("@strArchRoot", OleDbType.VarChar, 255).Value = strArchRoot
            .Add("@strArchStatus", OleDbType.VarChar, 100).Value = strArchStatus
        End With
        myConn.Open()
        myInsertCommand.ExecuteNonQuery()
        Using RetrieveNewIDCommand As New OleDbCommand("Select @@Identity From Archives,", myConn)
            NewID = CInt(RetrieveNewIDCommand.ExecuteScalar)
        End Using
    End Using
    Return NewID
End Function

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim NewID = InsertArchiveRetrieveID(txtUser.Text, txtDomain.Text, DateTimePicker1.Value, txtRoot.Text, txtStatus.Text)
    Dim strArchID = "Arch" & CStr(NewID)
    Dim strDirectoryName = "Archive" & CStr(NewID)
End Sub

【讨论】:

  • 请注意:INSERT 和 SELECT @@IDENTITY 之间的连接保持打开状态非常重要。一些程序员喜欢在每次 DB 交互后关闭连接。我也是,我也掉进了这个陷阱。这是您必须保持连接打开的例外情况。否则你什么也得不到,这意味着 0。
  • @Aranxo 好点!请参阅我的答案的第一行。
  • 是的,我看到了。我认为应该很清楚,但也许有人误解了这一点,并将连接视为由其连接字符串定义的同一个 DB,而不是与此连接相同的 opened 条件。所以并不是要批评你。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 2016-01-06
  • 1970-01-01
  • 2011-12-22
  • 2013-07-13
  • 1970-01-01
相关资源
最近更新 更多