向 Access 添加数据 table

Adding data to an Access table

我的应用程序通过 comport 读取秤并执行一些逻辑。然后我希望它将 6 个读数输出到 Access 数据库:

我从网上提取了这段代码,语句 dbInsert.ExcuteNonQuery () 得到了错误

data type mismatch in criteria expression

代码:

Dim dbInsert As New OleDb.OleDbCommand
Dim dbConnect As New OleDb.OleDbConnection
Dim Line As String = Environment.NewLine
Dim Status As String
Dim Stamp As Date
Dim pc As Double
Dim lc As Double

Sub AddToDb ()
    Try
        dbConnect.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source = C:\Users\aholiday\Desktop\Test\Test_be.accdb"
        dbConnect.Open()
        dbInsert.Parameters.Add(dbInsert.CreateParameter).ParameterName = "Date_Stamp"
        dbInsert.Parameters.Item("Date_Stamp").Value = Stamp
        dbInsert.Parameters.Add(dbInsert.CreateParameter).ParameterName = "Time_Stamp"
        dbInsert.Parameters.Item("Time_Stamp").Value = Stamp
        dbInsert.Parameters.Add(dbInsert.CreateParameter).ParameterName = "Status"
        dbInsert.Parameters.Item("Status").Value = Status
        dbInsert.Parameters.Add(dbInsert.CreateParameter).ParameterName = "Layer_Count"
        dbInsert.Parameters.Item("Layer_Count").Value = lc
        dbInsert.Parameters.Add(dbInsert.CreateParameter).ParameterName = "Part_Count"
        dbInsert.Parameters.Item("Part_Count").Value = pc
        dbInsert.Parameters.Add(dbInsert.CreateParameter).ParameterName = "Weight"
        dbInsert.Parameters.Item("Weight").Value = WeightAConvert
        Try
            dbInsert.CommandText = "INSERT INTO Log VALUES (Stamp,Stamp, Status, lc, pc, WeightAConvert);"
            dbInsert.CommandType = CommandType.Text
            dbInsert.Connection = dbConnect
            dbInsert.ExecuteNonQuery()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        Me.Close()
    End Try
End Sub

更新代码:

Try

        Dim SQL = "INSERT INTO Scale_Log (Date_Stamp,Time_Stamp, Status, Layer_Count, Part_Count, Weight) VALUES (Stamp,Stamp,Status,lc,pc,WeightAConvert)"

        Using dbCon As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source = C:\Users\aholiday\Desktop\Test\Line_6&7_Weight_Log_be.accdb")

            Using cmd As New OleDbCommand(SQL, dbCon)
                cmd.Parameters.Add("Date_Stamp", OleDbType.Date).Value = Stamp
                cmd.Parameters.Add("Time_Stamp", OleDbType.Date).Value = Stamp
                cmd.Parameters.Add("Status", OleDbType.VarChar).Value = Status
                cmd.Parameters.Add("Lay_Count", OleDbType.Double).Value = lc
                cmd.Parameters.Add("Part_Count", OleDbType.Double).Value = pc
                cmd.Parameters.Add("Weight", OleDbType.Double).Value = WeightAConvert
                dbCon.Open()
                Dim rows = cmd.ExecuteNonQuery()
                cmd.Dispose()
            End Using

            dbCon.Close()

            dbCon.Dispose()

        End Using
    Catch ex As Exception

        MessageBox.Show(ex.Message)

        Exit Sub
    End Try

您没有在 SQL 中指定列,因此您无法控制将哪个变量映射到哪个数据库列。当您恰好以正确的顺序添加参数时,它将起作用。不要碰运气:当它出错时,您可能会收到数据不匹配错误。

此外,您似乎正在使用全局 DBConnectionDBCommand 对象。 不要那样做,因为它会导致各种问题:

  • 从根本上说,DBCommand 对象是特定于查询的,因此它没有重用价值
  • 下次您使用该命令对象时,它已经定义了 6 个参数。这会导致下次参数太多。
  • 由于 DBCommand 对象需要引用连接(dbInsert.Connection = dbConnect 在您的代码中),如果不处理它,您也不会关闭或处理该连接。

当然,如果传递的数据类型与数据库列类型不匹配,可能会导致数据类型不匹配。你想要这样的东西:

Dim SQL = "INSERT INTO [Log] (colA, colB, colC...) VALUES (?,?,?,?,?,?)"

' dont use global provider objects
Using dbCon As New OleDbConnection(ACEConnStr)   ' use YOUR connection string
    Using cmd As New OleDbCommand(SQL, dbCon)

        ' do these in the exact same order as the cols are listed in the SQL
        cmd.Parameters.Add("?", OleDbType.Date).Value = Stamp       ' colA
        cmd.Parameters.Add("?", OleDbType.Date).Value = Stamp       ' colB
        cmd.Parameters.Add("?", OleDbType.VarChar).Value = Status
        '...
        cmd.Parameters.Add("?", OleDbType.Double).Value = ItemWeight 'colF
        dbCon.Open()
        Dim rows = cmd.ExecuteNonQuery()
    End Using
End Using
  • 首先,Log可能是Access-SQL中的保留字,所以我对名字1进行了转义。列及其顺序在 SQL 语句中指定。
  • SQL 中的 ?,?,?,? 列表是占位符。您也可以使用 @p1, @p2,@p3... 甚至名称,但 OleDB 将仅按位置使用它们(继续阅读)。
  • 每个 cmd.Parameters.Add("?",... 语句都提供了每个数据。这就是您的代码 maps/provides 中每个参数的值 SQL 的方式。
  • DateTime 列将包含日期和时间。我不确定为什么要将它们分开存放。
  • 与其他提供商一起,他们根据参数名称 (cmd.Parameters.Add("@firstName", ...).Value = myFirstNameVar) 映射值。 OleDB 不使用这样的命名参数,因此您必须完全相同的顺序 提供参数值,因为列名称出现在SQL.
  • Using创建目标对象供您使用,然后在最后关闭并处理它们。您的连接字符串可以是全局变量。

最后,考虑传递 layercount 之类的全局变量而不是全局变量:

Sub AddToDb(foo As String, Stamp As DateTime, lc As Double....)

1.我不确定在这种情况下是否真的如此,but it is on a list

另请参阅:MSDNUsing Statement