如何使用 DataRow 更新数据库?
How to update database using DataRow?
首先,我在全局中创建了 DataSet 和 MySQLDataAdapter。然后在 Form_Load 事件中,我像这样查询所有表。
dS = New DataSet
dA = New MySqlDataAdapter(myCommand)
Using sqlConn As New MySqlConnection(connStr)
myCommand = New MySqlCommand("Select ID, DevCompanyName from developer_name_table; Select ID, DevType from development_type_table; Select ID, Mukim from mukim_table; Select ID, Daerah from daerah_table; Select ID, Negeri from negeri_table; Select * from project_record ORDER BY FloatNo desc limit 1", sqlConn)
sqlConn.Open()
MsgBox("Connection open.")
Dim myCB As New MySqlCommandBuilder(dA)
dA.SelectCommand = myCommand
dA.UpdateCommand = myCB.GetUpdateCommand
dA.InsertCommand = myCB.GetInsertCommand
dA.DeleteCommand = myCB.GetDeleteCommand
dA.Fill(dS)
dA.FillSchema(dS, SchemaType.Source)
dS.Tables(0).TableName = "developer_name_table"
dS.Tables(1).TableName = "development_type_table"
dS.Tables(2).TableName = "mukim_table"
dS.Tables(3).TableName = "daerah_table"
dS.Tables(4).TableName = "negeri_table"
dS.Tables(5).TableName = "project_record"
End Using
一切正常,直到我尝试像这样将新记录添加到数据库中。下面的添加记录代码在一个按钮点击事件下。首先我检查记录是否存在,然后我像这样添加一个新行。
For Each r As DataRow In dS.Tables("project_record").Rows()
If r.Item("FloatNo") = TextBox1.Text.Trim() Then
MsgBox("Project exist. Please recheck.")
Exit Sub
End If
Next
SecurityAdd() 'This is just to fill None if field are empty.
Dim row = dS.Tables("project_record").NewRow()
row.Item("FloatNo") = TextBox1.Text.Trim()
row.Item("DevCompanyName") = ComboBox1.Text.Trim()
row.Item("DevType") = ComboBox2.Text.Trim()
row.Item("LotPt") = TextBox2.Text.Trim()
row.Item("Mukim") = ComboBox3.Text.Trim()
row.Item("Daerah") = ComboBox4.Text.Trim()
row.Item("Negeri") = ComboBox5.Text.Trim()
row.Item("TempReference") = RichTextBox1.Text.Trim()
row.Item("PermanentNo") = 0
row.Item("QuotationNo") = 0
row.Item("InvoiceNo") = 0
row.Item("Staff") = loggedUser.ToString() 'Just user ID.
dS.Tables("project_record").Rows.Add(row)
dA.Update(dS, "project_record")
更新后,我确定DataSet更新了,因为我第二次点击添加记录时,消息框告诉我该记录存在。但是当我检查我的数据库时,没有新记录?我在这里做错了什么?
下面是一个使用数据行显示数据插入的简单示例:
Module *GiveAModuleName*
Function GetTable() As DataTable
Dim table As DataTable = New DataTable
table.Columns.Add("ID", GetType(Integer))
table.Columns.Add("Name", GetType(String))
table.Columns.Add("Location", GetType(String))
table.Columns.Add("D.O.B.", GetType(DateTime))
table.Rows.Add(1, "Koko", "Sydney", 06/12/1990)
table.Rows.Add(2, "Fido", "Ottawa", 06/12/1990)
table.Rows.Add(3, "Alex", "California",06/12/1990)
table.Rows.Add(4, "Charles", "Malta", 06/12/1990)
table.Rows.Add(7, "Candy", "Delhi", 06/12/1990)
Return table
End Function
Sub Main()
Dim table As DataTable = GetTable()
End Sub
End Module
参考这个并重写现有代码以插入数据。
问题是您正在尝试将 DataAdapter
配置为在 DataSet
中的所有 6 个 table 上工作。如果查看构建的 INSERT 或 UPDATE 命令,您会发现它们是所有 table 中所有列的混合体。设置一个 DataAdapter
来为你完成繁重的工作对一个 table。
我不知道 negeri
和其他翻译成什么,但 看起来 只有一个是交易 table;其余的,如 DevCompanyName
似乎是 domain/code table,它们为项目记录 table 提供值。
通常,其中一些是根据业务规则固定的,那些不需要 add/update 的方法。其他人可能很需要一种方法来添加新项目,但只是偶尔。手动执行这些更新,以便可以设置 DA 并将其与应用程序关注的主要 table 一起使用。如果有用于添加 Mukim 等人的表格或选项卡,只需在那里插入并刷新即可。
至少,我会将这些域 table 存储在一个单独的 DataSet
中,这样它们就不会碍事,但是只使用一个域,您可以像这样配置它:
Using dbcon As New MySqlConnection(MySQLConnStr)
dsS = New DataSet
dbcon.Open()
' add table 1 - Mukim
dsS.Tables.Add("Mukim")
Using cmd As New MySqlCommand("SELECT DeptCode, Descr FROM Department", dbcon)
dsS.Tables("Mukim").Load(cmd.ExecuteReader())
cboColors.DataSource = dsS.Tables("Mukim")
cboColors.DisplayMember = "Descr" ' ie "Management"
cboColors.ValueMember = "DeptCode" ' eg "MGMT"
End Using
' add table 2 - negeri
' this table is fixed - new rows are very rare
Using cmd As New MySqlCommand("SELECT DeptCode, Descr FROM cDepartment", dbcon)
Dim dt As New DataTable
dt.Load(cmd.ExecuteReader)
cboDept.DataSource = dt
cboDept.DisplayMember = "Descr" ' "Sommelier"
cboDept.ValueMember = "DeptCode" ' "SOMM"
End Using
' etc
' main transaction table - project
' do this last
Dim prjcmd = New MySqlCommand(prjSql, dbcon)
daSample = New MySqlDataAdapter(prjcmd)
Dim cb As New MySqlCommandBuilder(daSample)
daSample.SelectCommand = prjcmd
daSample.InsertCommand = cb.GetInsertCommand
' etc
dsS.Tables.Add("Project")
daSample.Fill(dsS.Tables("Project"))
daSample.FillSchema(dsS.Tables("Project"), SchemaType.Source)
End Using
代码将 domain/code table 存储在 DataSet
中,以备可能更改。它们不是适配器,而是使用 DataReader
填充的。任何已修复的内容(例如 "Department")都会发布到相关的 CBO 并被遗忘。根据每个实际更新的频率,您可以对所有这些方法使用此方法,并在它们获得新行时绑定到新的 table。
该代码还使用作为相关 CBO 的 DataSource
创建的 DataTable
。我不确定您的代码在做什么,因为它存储了 Combobox.Text
。如果我用新条目更新 DataTable
,它可以编码为自动显示。
结果是 DataAdapter
知道如何更新主项目 table 等,并且不会被其他 table 混淆。然后插入就和你拥有的差不多了:
Dim dr = dsS.Tables("Project").NewRow
dr("Name") = "My New Row"
dr("Mukim") = cboMukim.SelectedValue ' MGMT
... etc
dsS.Tables(1).Rows.Add(dr)
daSample.Update(dsS.Tables("Project"))
dsS.Tables("Project").AcceptChanges()
' See Notes
Dim rows = daSample.Fill(dsS.Tables("Project")) ' refresh
dsS.Tables("Project").Rows.Remove(dr)
- 由于现在绑定了Mukim CBO,使用
SelectedValue
存储到项目中。
DataTable
跟踪哪些行是新的、添加的、删除的等。更新后,使用 AcceptChanges
清除这些标志。
- 在 table 使用 AI PK 的情况下,新行最初将为 0。如果刷新项目 table,您将获得 new 使用数据库提供的 PK 进行记录。这意味着 "My New Row" 会有 2 条记录,一条带有实际数据库提供的 ID,另一条为零。删除(不是删除!)我们添加的新行消除了这一点。
不清楚第 3 项是否适用。 FloatNo
可能是 PK,在这种情况下,您可以跳过删除。此外,循环遍历 "all" 行以查看 "FloatNo" 是否存在只会循环遍历加载的一 (1) 行,因为查询包含 LIMTI 1
子句。
并非毫无意义,但您可以使用 DataGridView
来简化 UI。 Mukim 等人不是表单上的组合框,而是 ComboBox 列,以便为您添加新行到 table。您只需要在验证 and/or 他们点击保存后进行更新。
首先,我在全局中创建了 DataSet 和 MySQLDataAdapter。然后在 Form_Load 事件中,我像这样查询所有表。
dS = New DataSet
dA = New MySqlDataAdapter(myCommand)
Using sqlConn As New MySqlConnection(connStr)
myCommand = New MySqlCommand("Select ID, DevCompanyName from developer_name_table; Select ID, DevType from development_type_table; Select ID, Mukim from mukim_table; Select ID, Daerah from daerah_table; Select ID, Negeri from negeri_table; Select * from project_record ORDER BY FloatNo desc limit 1", sqlConn)
sqlConn.Open()
MsgBox("Connection open.")
Dim myCB As New MySqlCommandBuilder(dA)
dA.SelectCommand = myCommand
dA.UpdateCommand = myCB.GetUpdateCommand
dA.InsertCommand = myCB.GetInsertCommand
dA.DeleteCommand = myCB.GetDeleteCommand
dA.Fill(dS)
dA.FillSchema(dS, SchemaType.Source)
dS.Tables(0).TableName = "developer_name_table"
dS.Tables(1).TableName = "development_type_table"
dS.Tables(2).TableName = "mukim_table"
dS.Tables(3).TableName = "daerah_table"
dS.Tables(4).TableName = "negeri_table"
dS.Tables(5).TableName = "project_record"
End Using
一切正常,直到我尝试像这样将新记录添加到数据库中。下面的添加记录代码在一个按钮点击事件下。首先我检查记录是否存在,然后我像这样添加一个新行。
For Each r As DataRow In dS.Tables("project_record").Rows()
If r.Item("FloatNo") = TextBox1.Text.Trim() Then
MsgBox("Project exist. Please recheck.")
Exit Sub
End If
Next
SecurityAdd() 'This is just to fill None if field are empty.
Dim row = dS.Tables("project_record").NewRow()
row.Item("FloatNo") = TextBox1.Text.Trim()
row.Item("DevCompanyName") = ComboBox1.Text.Trim()
row.Item("DevType") = ComboBox2.Text.Trim()
row.Item("LotPt") = TextBox2.Text.Trim()
row.Item("Mukim") = ComboBox3.Text.Trim()
row.Item("Daerah") = ComboBox4.Text.Trim()
row.Item("Negeri") = ComboBox5.Text.Trim()
row.Item("TempReference") = RichTextBox1.Text.Trim()
row.Item("PermanentNo") = 0
row.Item("QuotationNo") = 0
row.Item("InvoiceNo") = 0
row.Item("Staff") = loggedUser.ToString() 'Just user ID.
dS.Tables("project_record").Rows.Add(row)
dA.Update(dS, "project_record")
更新后,我确定DataSet更新了,因为我第二次点击添加记录时,消息框告诉我该记录存在。但是当我检查我的数据库时,没有新记录?我在这里做错了什么?
下面是一个使用数据行显示数据插入的简单示例:
Module *GiveAModuleName*
Function GetTable() As DataTable
Dim table As DataTable = New DataTable
table.Columns.Add("ID", GetType(Integer))
table.Columns.Add("Name", GetType(String))
table.Columns.Add("Location", GetType(String))
table.Columns.Add("D.O.B.", GetType(DateTime))
table.Rows.Add(1, "Koko", "Sydney", 06/12/1990)
table.Rows.Add(2, "Fido", "Ottawa", 06/12/1990)
table.Rows.Add(3, "Alex", "California",06/12/1990)
table.Rows.Add(4, "Charles", "Malta", 06/12/1990)
table.Rows.Add(7, "Candy", "Delhi", 06/12/1990)
Return table
End Function
Sub Main()
Dim table As DataTable = GetTable()
End Sub
End Module
参考这个并重写现有代码以插入数据。
问题是您正在尝试将 DataAdapter
配置为在 DataSet
中的所有 6 个 table 上工作。如果查看构建的 INSERT 或 UPDATE 命令,您会发现它们是所有 table 中所有列的混合体。设置一个 DataAdapter
来为你完成繁重的工作对一个 table。
我不知道 negeri
和其他翻译成什么,但 看起来 只有一个是交易 table;其余的,如 DevCompanyName
似乎是 domain/code table,它们为项目记录 table 提供值。
通常,其中一些是根据业务规则固定的,那些不需要 add/update 的方法。其他人可能很需要一种方法来添加新项目,但只是偶尔。手动执行这些更新,以便可以设置 DA 并将其与应用程序关注的主要 table 一起使用。如果有用于添加 Mukim 等人的表格或选项卡,只需在那里插入并刷新即可。
至少,我会将这些域 table 存储在一个单独的 DataSet
中,这样它们就不会碍事,但是只使用一个域,您可以像这样配置它:
Using dbcon As New MySqlConnection(MySQLConnStr)
dsS = New DataSet
dbcon.Open()
' add table 1 - Mukim
dsS.Tables.Add("Mukim")
Using cmd As New MySqlCommand("SELECT DeptCode, Descr FROM Department", dbcon)
dsS.Tables("Mukim").Load(cmd.ExecuteReader())
cboColors.DataSource = dsS.Tables("Mukim")
cboColors.DisplayMember = "Descr" ' ie "Management"
cboColors.ValueMember = "DeptCode" ' eg "MGMT"
End Using
' add table 2 - negeri
' this table is fixed - new rows are very rare
Using cmd As New MySqlCommand("SELECT DeptCode, Descr FROM cDepartment", dbcon)
Dim dt As New DataTable
dt.Load(cmd.ExecuteReader)
cboDept.DataSource = dt
cboDept.DisplayMember = "Descr" ' "Sommelier"
cboDept.ValueMember = "DeptCode" ' "SOMM"
End Using
' etc
' main transaction table - project
' do this last
Dim prjcmd = New MySqlCommand(prjSql, dbcon)
daSample = New MySqlDataAdapter(prjcmd)
Dim cb As New MySqlCommandBuilder(daSample)
daSample.SelectCommand = prjcmd
daSample.InsertCommand = cb.GetInsertCommand
' etc
dsS.Tables.Add("Project")
daSample.Fill(dsS.Tables("Project"))
daSample.FillSchema(dsS.Tables("Project"), SchemaType.Source)
End Using
代码将 domain/code table 存储在 DataSet
中,以备可能更改。它们不是适配器,而是使用 DataReader
填充的。任何已修复的内容(例如 "Department")都会发布到相关的 CBO 并被遗忘。根据每个实际更新的频率,您可以对所有这些方法使用此方法,并在它们获得新行时绑定到新的 table。
该代码还使用作为相关 CBO 的 DataSource
创建的 DataTable
。我不确定您的代码在做什么,因为它存储了 Combobox.Text
。如果我用新条目更新 DataTable
,它可以编码为自动显示。
结果是 DataAdapter
知道如何更新主项目 table 等,并且不会被其他 table 混淆。然后插入就和你拥有的差不多了:
Dim dr = dsS.Tables("Project").NewRow
dr("Name") = "My New Row"
dr("Mukim") = cboMukim.SelectedValue ' MGMT
... etc
dsS.Tables(1).Rows.Add(dr)
daSample.Update(dsS.Tables("Project"))
dsS.Tables("Project").AcceptChanges()
' See Notes
Dim rows = daSample.Fill(dsS.Tables("Project")) ' refresh
dsS.Tables("Project").Rows.Remove(dr)
- 由于现在绑定了Mukim CBO,使用
SelectedValue
存储到项目中。 DataTable
跟踪哪些行是新的、添加的、删除的等。更新后,使用AcceptChanges
清除这些标志。- 在 table 使用 AI PK 的情况下,新行最初将为 0。如果刷新项目 table,您将获得 new 使用数据库提供的 PK 进行记录。这意味着 "My New Row" 会有 2 条记录,一条带有实际数据库提供的 ID,另一条为零。删除(不是删除!)我们添加的新行消除了这一点。
不清楚第 3 项是否适用。 FloatNo
可能是 PK,在这种情况下,您可以跳过删除。此外,循环遍历 "all" 行以查看 "FloatNo" 是否存在只会循环遍历加载的一 (1) 行,因为查询包含 LIMTI 1
子句。
并非毫无意义,但您可以使用 DataGridView
来简化 UI。 Mukim 等人不是表单上的组合框,而是 ComboBox 列,以便为您添加新行到 table。您只需要在验证 and/or 他们点击保存后进行更新。