向 Access 添加数据 table
Adding data to an Access table
我的应用程序通过 comport 读取秤并执行一些逻辑。然后我希望它将 6 个读数输出到 Access 数据库:
- date/time两次
- 状态
- 层数
- 零件数
- 体重秤
我从网上提取了这段代码,语句 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 中指定列,因此您无法控制将哪个变量映射到哪个数据库列。当您恰好以正确的顺序添加参数时,它将起作用。不要碰运气:当它出错时,您可能会收到数据不匹配错误。
此外,您似乎正在使用全局 DBConnection
和 DBCommand
对象。 不要那样做,因为它会导致各种问题:
- 从根本上说,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
我的应用程序通过 comport 读取秤并执行一些逻辑。然后我希望它将 6 个读数输出到 Access 数据库:
- date/time两次
- 状态
- 层数
- 零件数
- 体重秤
我从网上提取了这段代码,语句 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 中指定列,因此您无法控制将哪个变量映射到哪个数据库列。当您恰好以正确的顺序添加参数时,它将起作用。不要碰运气:当它出错时,您可能会收到数据不匹配错误。
此外,您似乎正在使用全局 DBConnection
和 DBCommand
对象。 不要那样做,因为它会导致各种问题:
- 从根本上说,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