2016-08-25 89 views
2

我的应用程序通过comport读取比例,并执行一些逻辑。然后,我希望它输出6个读数到Access数据库:将数据添加到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

您的SQL不会执行任何操作来将值映射到col UMNS。如果数据库不按照这个顺序返回列,那么你会试图将一些东西放入绞线列。 SQL应该包含参数,而不是与其他数据库提供者有关的变量(“Date_Stamp”而不是“Stamp”)。另外,打开Option Strict - 'layerCount'和其他一些没有在代码中声明的我们可以看到 – Plutonix

+0

@Plutonix我没有真正明白你的意思,你说'dbInsert.Parameters.Add(dbInsert.CreateParameter).ParameterName =“Date_Stamp”dbInsert.Parameters.Item(“Date_Stamp”)。Value = Stamp',这是2000行代码片断,LayerCount被声明为else – holi4683

回答

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的保留字,所以我逃过了名。这些列及其顺序在SQL语句中指定。
  • SQL中的?,?,?,?列表是占位符。您也可以使用@p1, @p2,@p3...或甚至名称,但OleDB将按位置使用它们(继续阅读)。
  • 每个数据都随每个cmd.Parameters.Add("?",...声明一起提供。这就是您的代码如何映射/提供SQL中每个参数的值。
  • A DateTime列将包含日期和时间。我不确定你为什么单独存储它们。
  • 与其他提供者一起,他们根据参数名称(cmd.Parameters.Add("@firstName", ...).Value = myFirstNameVar)映射值。 OleDB不使用命名参数,因此必须提供中的参数值,因为列名出现在SQL中,所以完全相同的顺序为
  • Using blocks 创建目标对象供您使用,然后在最后关闭并处理它们。您的连接字符串可以是全局变量。

最后,而不是搞什么layercount全局变量考虑通过他们:

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

1.我不知道这是在这种情况下实际上是真的,but it is on a list

参见:Using Statement on MSDN