将数据添加到Access表

时间:2016-08-25 20:22:42

标签: .net vb.net ms-access oledb

我的应用程序通过comport读取一个比例并做一些逻辑。然后我想让它输出6个读数到Access数据库:

  • 两次日期/时间
  • 状态
  • 图层数
  • 零件计数
  • 比例重量

我从在线提取此代码,语句dbInsert.ExcuteNonQuery ()收到错误

  

标准表达式中的数据类型不匹配

代码:

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

1 个答案:

答案 0 :(得分:3)

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

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

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

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

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("?",...语句都提供了每个数据。这是您的代码映射/提供SQL中每个参数的值的方式。
  • DateTime列将包含日期和时间。我不确定你为什么要单独存放它们。
  • 使用其他提供商,他们会根据参数名称(cmd.Parameters.Add("@firstName", ...).Value = myFirstNameVar)映射值。 OleDB不会使用这样的命名参数,因此必须提供完全相同的顺序的参数值,因为列名出现在SQL中。
  • Using阻止创建目标对象供您使用,然后在最后关闭并处理它们。您的connectionstring可以是全局变量。

最后,考虑传递它们,而不是像layercount这样的全局变量:

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

1。在这种情况下,我不确定这是否属实,but it is on a list

另请参阅:MSDN上的 Using Statement