SQLite 错误 20:数据库插入中的数据类型不匹配
SQLite Error 20: Datatype mismatch in database insertion
我正在制作一个 POS 样式系统,这是我用于存储活动订单数据并将数据输入数据库的代码。这应该一切正常,但是我在“Push”IF 语句中的 cmd.ExecuteNonQuery() 上收到错误。
它给我一个 SQLite 错误 20:数据类型不匹配。
为什么?
TIA
Imports Microsoft.Data.Sqlite
Public Class CurrentOrder
Public Shared OrderID As Integer
Public Shared Items As New ArrayList
Public Shared ItemsString As String
Public Shared CustName As String
Public Shared Table As Integer
Public Shared Cost As Double 'How much the restaurant will have to pay to make the meal
Public Shared Price As Double 'How much the customer will pay for this order
Public Shared Sub Database(ByVal Mode As String)
Dim Connection As New SqliteConnection("Data Source = Database.db")
Dim SQLcommand As String
Dim CMD As New SqliteCommand
'ItemsString = ""
If Items.Count = 0 Then
MessageBox.Show("Please add items to order", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End If
If Mode = "Push" Then
For i = 0 To Items.Count - 1
ItemsString = ItemsString + Items(i) 'Concatatanation to take a list to a string
Next
Order.Label3.Text = ItemsString
SQLcommand = "INSERT INTO Orders VALUES ('@OrderID', '@ItemsString', '@CustName', '@Table', '@Cost', '@Price')" 'SQL Push Statement
Try
CMD.Connection = Connection
Connection.Open()
CMD.CommandText = SQLcommand
CMD.ExecuteNonQuery() 'Error 20: Datatype mismatch
Connection.Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
ElseIf Mode = "Pull" Then
SQLcommand = ("SELECT * FROM Orders WHERE OrderID = " & OrderID) 'SQL Pull Statement
Try
CMD.Connection = Connection
Connection.Open()
CMD.CommandText = SQLcommand
Dim reader As SqliteDataReader = CMD.ExecuteReader()
While reader.Read()
Order.Label3.Text = reader("ItemID") & ", " & reader("Name") & ", " & reader("Price")
End While
reader.Close()
Connection.Close()
Catch e As Exception
MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
End Sub
End Class
在 table 中,您有不同的数据类型,并且您正在发送不同的数据类型。例如,在 table 中,您使用 Int 并传递 decimal.
在处理金钱时,最好使用 Decimal
而不是 Double
。
我不知道为什么这个 class 有所有这些 Shared
项。在调用代码中创建一个实例可能会更好。
ArrayList
不应在新代码中使用。看看 List(Of T)
是否会填满账单。
字段在 Classe
中通常 Public
。您希望 Property
成为 Public
.
Class像这样的没有用户界面。您不想显示 class 中的消息框。在表单 Class.
中显示来自用户界面代码的消息框
不要在数据库的单个字段中存储多个项目。你应该有一个 Orders
table 主键 OrderID
和一个 OrderDetails
table 的项目。
您的 for 循环只是将所有项目集中在一起。如果没有任何分隔符,您将无法再次将它们分开。此外,vb.net 中的串联运算符是 &
.
对于插入语句,通常最好列出字段名称,然后列出值。我不知道你为什么用单引号将参数名称括起来。
您可以将 CommandText
和 Connection
直接传递给命令的构造函数。
您在插入中引用了多个参数,但从未将它们添加到参数集合中或为它们设置值。
显然,您为 OrderID
提供了唯一值,这不是自动编号字段。
使用 Sub New
将您的订单对象置于 stable 状态,准备好将其数据添加到数据库中。
Public Class CurrentOrder
Public Property OrderID As Integer
Public Property Items As New List(Of String)
Public Property CustName As String
Public Property Table As Integer
Public Property Cost As Decimal 'How much the restaurant will have to pay to make the meal
Public Property Price As Decimal 'How much the customer will pay for this order
Public Sub New(ID As Integer, Itms As List(Of String), Name As String, TBL As Integer, Cst As Decimal, Prc As Decimal)
OrderID = ID
Items = Itms
CustName = Name
Table = TBL
Cost = Cst
Price = Prc
End Sub
End Class
CurrentOrder
class 与 DataAccess
class 完全分开。
Public Class DataAccess
Private ConStr As String = "Data Source = Database.db"
Public Sub SaveOrderAndDetails(O As CurrentOrder)
Dim OrderInsert = "INSERT INTO Orders (OrderID, CustName, Table, Cost, Price) VALUES (@OrderID, @CustName, @Table, @Cost, @Price)"
Using Connection As New SQLiteConnection(ConStr)
Using CMD As New SQLiteCommand(OrderInsert, Connection)
CMD.Parameters.Add("@OrderID", DbType.Int32).Value = O.OrderID
CMD.Parameters.Add("@CustName", DbType.String).Value = O.CustName
CMD.Parameters.Add("@Table", DbType.Int32).Value = O.Table
CMD.Parameters.Add("@Cost", DbType.Decimal).Value = O.Cost
CMD.Parameters.Add("@Price", DbType.Decimal).Value = O.Price
Connection.Open()
CMD.ExecuteNonQuery()
End Using
Dim DetailsInsert = "Insert Into OrderDetails (OrderID, Item) Values (@OrderId, @Item)"
Using cmd As New SQLiteCommand(DetailsInsert, Connection)
cmd.Parameters.Add("@OrderId", DbType.Int32).Value = O.OrderID
cmd.Parameters.Add("@Item", DbType.String)
For Each s In O.Items
cmd.Parameters("@Item").Value = s
cmd.ExecuteNonQuery()
Next
End Using
End Using
End Sub
Public Function GetOrderByID(id As Integer) As DataTable
Dim dt As New DataTable
Dim SqlCommand = "SELECT * FROM Orders WHERE OrderID = @ID"
Using cn As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(SqlCommand, cn)
cmd.Parameters.Add("@ID", DbType.Int32).Value = id
cn.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
Public Function GetOrderDetailByID(id As Integer) As DataTable
Dim dt As New DataTable
Dim sql = "Select Item From OrderDetails Where OrderID = @ID"
Using cn As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(sql, cn)
cmd.Parameters.Add("@ID", DbType.Int32).Value = id
cn.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
End Class
最后,在用户界面中使用 classes,在本例中为 windows 表单。
Private Sub Button1_Click() Handles Button1.Click
Dim lst As New List(Of String)
lst.Add("Bacon")
lst.Add("Eggs")
Dim newOrder As New CurrentOrder(7, lst, "John", 4, 12.03D, 22D)
Dim DA As New DataAccess
DA.SaveOrderAndDetails(newOrder)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim DA As New DataAccess
Dim dt = DA.GetOrderByID(7)
'Fill various text boxes with the DataTable fields
Dim dt2 = DA.GetOrderDetailByID(7)
DataGridView1.DataSource = dt2
End Sub
我正在制作一个 POS 样式系统,这是我用于存储活动订单数据并将数据输入数据库的代码。这应该一切正常,但是我在“Push”IF 语句中的 cmd.ExecuteNonQuery() 上收到错误。
它给我一个 SQLite 错误 20:数据类型不匹配。
为什么?
TIA
Imports Microsoft.Data.Sqlite
Public Class CurrentOrder
Public Shared OrderID As Integer
Public Shared Items As New ArrayList
Public Shared ItemsString As String
Public Shared CustName As String
Public Shared Table As Integer
Public Shared Cost As Double 'How much the restaurant will have to pay to make the meal
Public Shared Price As Double 'How much the customer will pay for this order
Public Shared Sub Database(ByVal Mode As String)
Dim Connection As New SqliteConnection("Data Source = Database.db")
Dim SQLcommand As String
Dim CMD As New SqliteCommand
'ItemsString = ""
If Items.Count = 0 Then
MessageBox.Show("Please add items to order", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End If
If Mode = "Push" Then
For i = 0 To Items.Count - 1
ItemsString = ItemsString + Items(i) 'Concatatanation to take a list to a string
Next
Order.Label3.Text = ItemsString
SQLcommand = "INSERT INTO Orders VALUES ('@OrderID', '@ItemsString', '@CustName', '@Table', '@Cost', '@Price')" 'SQL Push Statement
Try
CMD.Connection = Connection
Connection.Open()
CMD.CommandText = SQLcommand
CMD.ExecuteNonQuery() 'Error 20: Datatype mismatch
Connection.Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
ElseIf Mode = "Pull" Then
SQLcommand = ("SELECT * FROM Orders WHERE OrderID = " & OrderID) 'SQL Pull Statement
Try
CMD.Connection = Connection
Connection.Open()
CMD.CommandText = SQLcommand
Dim reader As SqliteDataReader = CMD.ExecuteReader()
While reader.Read()
Order.Label3.Text = reader("ItemID") & ", " & reader("Name") & ", " & reader("Price")
End While
reader.Close()
Connection.Close()
Catch e As Exception
MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
End Sub
End Class
在 table 中,您有不同的数据类型,并且您正在发送不同的数据类型。例如,在 table 中,您使用 Int 并传递 decimal.
在处理金钱时,最好使用 Decimal
而不是 Double
。
我不知道为什么这个 class 有所有这些 Shared
项。在调用代码中创建一个实例可能会更好。
ArrayList
不应在新代码中使用。看看 List(Of T)
是否会填满账单。
字段在 Classe
中通常 Public
。您希望 Property
成为 Public
.
Class像这样的没有用户界面。您不想显示 class 中的消息框。在表单 Class.
中显示来自用户界面代码的消息框不要在数据库的单个字段中存储多个项目。你应该有一个 Orders
table 主键 OrderID
和一个 OrderDetails
table 的项目。
您的 for 循环只是将所有项目集中在一起。如果没有任何分隔符,您将无法再次将它们分开。此外,vb.net 中的串联运算符是 &
.
对于插入语句,通常最好列出字段名称,然后列出值。我不知道你为什么用单引号将参数名称括起来。
您可以将 CommandText
和 Connection
直接传递给命令的构造函数。
您在插入中引用了多个参数,但从未将它们添加到参数集合中或为它们设置值。
显然,您为 OrderID
提供了唯一值,这不是自动编号字段。
使用 Sub New
将您的订单对象置于 stable 状态,准备好将其数据添加到数据库中。
Public Class CurrentOrder
Public Property OrderID As Integer
Public Property Items As New List(Of String)
Public Property CustName As String
Public Property Table As Integer
Public Property Cost As Decimal 'How much the restaurant will have to pay to make the meal
Public Property Price As Decimal 'How much the customer will pay for this order
Public Sub New(ID As Integer, Itms As List(Of String), Name As String, TBL As Integer, Cst As Decimal, Prc As Decimal)
OrderID = ID
Items = Itms
CustName = Name
Table = TBL
Cost = Cst
Price = Prc
End Sub
End Class
CurrentOrder
class 与 DataAccess
class 完全分开。
Public Class DataAccess
Private ConStr As String = "Data Source = Database.db"
Public Sub SaveOrderAndDetails(O As CurrentOrder)
Dim OrderInsert = "INSERT INTO Orders (OrderID, CustName, Table, Cost, Price) VALUES (@OrderID, @CustName, @Table, @Cost, @Price)"
Using Connection As New SQLiteConnection(ConStr)
Using CMD As New SQLiteCommand(OrderInsert, Connection)
CMD.Parameters.Add("@OrderID", DbType.Int32).Value = O.OrderID
CMD.Parameters.Add("@CustName", DbType.String).Value = O.CustName
CMD.Parameters.Add("@Table", DbType.Int32).Value = O.Table
CMD.Parameters.Add("@Cost", DbType.Decimal).Value = O.Cost
CMD.Parameters.Add("@Price", DbType.Decimal).Value = O.Price
Connection.Open()
CMD.ExecuteNonQuery()
End Using
Dim DetailsInsert = "Insert Into OrderDetails (OrderID, Item) Values (@OrderId, @Item)"
Using cmd As New SQLiteCommand(DetailsInsert, Connection)
cmd.Parameters.Add("@OrderId", DbType.Int32).Value = O.OrderID
cmd.Parameters.Add("@Item", DbType.String)
For Each s In O.Items
cmd.Parameters("@Item").Value = s
cmd.ExecuteNonQuery()
Next
End Using
End Using
End Sub
Public Function GetOrderByID(id As Integer) As DataTable
Dim dt As New DataTable
Dim SqlCommand = "SELECT * FROM Orders WHERE OrderID = @ID"
Using cn As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(SqlCommand, cn)
cmd.Parameters.Add("@ID", DbType.Int32).Value = id
cn.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
Public Function GetOrderDetailByID(id As Integer) As DataTable
Dim dt As New DataTable
Dim sql = "Select Item From OrderDetails Where OrderID = @ID"
Using cn As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(sql, cn)
cmd.Parameters.Add("@ID", DbType.Int32).Value = id
cn.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
End Class
最后,在用户界面中使用 classes,在本例中为 windows 表单。
Private Sub Button1_Click() Handles Button1.Click
Dim lst As New List(Of String)
lst.Add("Bacon")
lst.Add("Eggs")
Dim newOrder As New CurrentOrder(7, lst, "John", 4, 12.03D, 22D)
Dim DA As New DataAccess
DA.SaveOrderAndDetails(newOrder)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim DA As New DataAccess
Dim dt = DA.GetOrderByID(7)
'Fill various text boxes with the DataTable fields
Dim dt2 = DA.GetOrderDetailByID(7)
DataGridView1.DataSource = dt2
End Sub