将列从 DGV 添加到 SQL 服务器的问题
Posted
技术标签:
【中文标题】将列从 DGV 添加到 SQL 服务器的问题【英文标题】:Issues adding column from DGV to SQL server 【发布时间】:2016-10-10 03:05:11 【问题描述】:对不起,如果标题有点含糊,但我不知道如何把它放在一个短的空间里。
对于上下文,我有一个保存按钮,用于在 SQL Server 数据库中更新所做的更改。这在添加行或更改值,甚至删除行时都可以正常工作。那里没有错。
但是,当我尝试添加或删除列时,应用程序变得有点问题,并且根本不会更新数据库中添加/删除的列并且不会引发错误。
我可以添加或删除列的唯一方法是在添加/删除按钮上使用 sql 查询,但这会直接保存到服务器 - 这是我不想要的。
我需要的是将更改显示在表中,然后仅在单击保存按钮时更新数据库。
我的代码在这里 --- (注意,这是在三个表单上完成的,我有带有表格的主表单,另外还有两个用于输入要添加的“培训师列”的名称或删除)
Private Function save() ''''' Main form
Try
ds.Tables(0).AcceptChanges()
da.Update(ds)
DataTableColours()
MessageBox.Show("Data updated successfully.")
Catch
MessageBox.Show("Data failed to update properly. Please ensure you are connected to the Baltic network and try again. If the problem persists, seek IT support.")
End Try
End Function
Public Function AddTrainerFunc() ''''' Main form
'Dim SqlAddCol As String = "ALTER TABLE MasterTrainerSchedule ADD [" & TrainerName.Trim() & "] nvarchar(255)"
'Using con As New OleDbConnection(cs)
' Using cmd As New OleDbCommand(SqlAddCol, con)
' con.Open()
' cmd.ExecuteNonQuery()
' End Using
'End Using
ds.Tables(0).Columns.Add(TrainerName.Trim()).DefaultValue = " "
RefreshBtn()
End Function
Public Function delTrainerFunc() ''''' Main form
Dim SqlDelCol As String = "ALTER TABLE MasterTrainerSchedule DROP COLUMN [" & TrainerName.Trim() & "]"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlDelCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
ds.Tables(0).Columns.Remove(TrainerName)
DelTrainer.Close()
RefreshBtn()
MessageBox.Show("Trainer '" & TrainerName.Trim() & "' has been deleted from the table.")
End Function
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click '''''Add Column Form
If Not txtTrainerName.Text = "Trainer Name Here" Or txtTrainerName.Text = "" Then
MTS.TrainerName = txtTrainerName.Text
MTS.Enabled = True
Me.Close()
MTS.AddTrainerFunc()
Else
MessageBox.Show("Please input a name for the trainer in the text box above.")
End If
End Sub
Private Sub btnDel_Click(sender As Object, e As EventArgs) Handles btnDel.Click ''''' Delete Column form
Dim delYN As Integer = MessageBox.Show("Are you sure you want to delete '" & cmbTrainers.Text & "' from the MTS table? The action will be permanent!", "Delete Trainer?", MessageBoxButtons.YesNo)
If delYN = DialogResult.Yes Then
MTS.Enabled = True
MTS.delTrainerFunc()
End If
End Sub
对不起,如果这有点冗长,但是......我似乎无法找到一种方法将列添加到数据库中,这也是我想要的,既不是通过谷歌搜索答案,也不是通过简单的实验,所以我来了在这里,希望你们中的一个人能够提供帮助。提前感谢您提供的任何帮助。
编辑 --- 如果有帮助,我正在使用 oleDB 作为到 sql 的连接。
编辑 2 --- 这里有一些屏幕截图,以防您想看看应用程序的视觉方面。
The add form being used. (with the main form in the background. Sorry I couldnt get that on its own - only allowed two links with 6 rep!)
And the delete trainer form. The dropdown lists everyone in the table for you, then prompts you when you click "delete"
编辑 3 --- 好的,我知道 Sean 所讨论的规范化表可能会奏效,但它可能需要对所使用的服务器和程序进行相当大的更改。我设法找到了一种更简单的方法来完成这项工作,即调用 sql 查询以在保存时向表中添加或删除列,仅在对数据网格进行更改之后。
这里有一些代码,以防有人感兴趣。它有点乱,可能可以稍微优化一下,但这对我来说无论如何都有效。 ` 私有函数 save()
Try
da.Update(ds)
DataTableColours()
MessageBox.Show("Data updated successfully.")
Catch
MessageBox.Show("Data failed to update properly. Please ensure you are connected to the Baltic network and try again. If the problem persists, seek IT support.")
End Try
'This section reads the SQL server for column names, and adds any that are listed in the DGV, but not the database. I know its a little messy but itll do.
Dim columnnum As Integer = -1
Dim columname As String
For Each column In ds.Tables(0).Columns
columnnum = columnnum + 1
columname = dgvSchedule.Columns(columnnum).HeaderText
If Not ds2.Tables(0).Columns.Contains(columname) Then
MessageBox.Show("Table does not include " & columname)
Dim SqlAddCol As String = "ALTER TABLE MasterTrainerSchedule ADD [" & columname.Trim() & "] nvarchar(255)"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlAddCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End If
Next
columnnum = -1
For Each column In ds2.Tables(0).Columns
columnnum = columnnum + 1
columname = ds2.Tables(0).Columns(columnnum).ColumnName
If Not ds.Tables(0).Columns.Contains(columname) Then
MessageBox.Show("Will Delete " & columname)
Dim SqlDelCol As String = "ALTER TABLE MasterTrainerSchedule DROP COLUMN [" & columname.Trim() & "]"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlDelCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End If
Next
ds2.Tables.Clear()
da2 = New OleDbDataAdapter(sql, cs)
da2.Fill(ds2)
End Function`
【问题讨论】:
ALTER TABLE...
遇到什么错误?
就是这样。在此期间我没有收到错误。问题更多与在运行添加或删除函数时使用 SQL 查询有关,此时我只希望它显示在数据网格视图中。一旦我点击“保存”按钮(显然它运行保存功能),我只想从 SQL 服务器数据库中添加或删除列
知道我忘了提一些事情 - 我正在使用 oleDB 连接到 SQL,这个命令显然不是 oleDB 的成员。
它应该可以工作。看看这里回答social.technet.microsoft.com/Forums/sqlserver/en-US/…
这是非规范化表的尖叫声。您的表中不应为每个培训师提供一列。这根本不是一个好的设计。
【参考方案1】:
我不知道你在这里做什么的很多细节,但这里有一个更规范化方法的例子。
create table Trainers
(
TrainerID int identity
, FirstName varchar(25)
, LastName varchar(25)
, CONSTRAINT PK_Trainers PRIMARY KEY CLUSTERED (TrainerID)
)
create table Courses
(
CourseID int identity
, CourseName varchar(50)
, CONSTRAINT PK_Courses PRIMARY KEY CLUSTERED (CourseID)
)
create table TrainerCourses
(
TrainerID int not null
, CourseID int not null
, StartDate date not null
, EndDate date not null
, DailyStartTime time not null
, CONSTRAINT PK_TrainerCourses PRIMARY KEY CLUSTERED (TrainerID, CourseID, StartDate, DailyStartTime)
, CONSTRAINT FK_TrainerCourses_Trainers FOREIGN KEY (TrainerID) REFERENCES Trainers(TrainerID)
, CONSTRAINT FK_TrainerCourses_Courses FOREIGN KEY (CourseID) REFERENCES Courses(CourseID)
)
【讨论】:
我不确定我是否很好地解释了我对他的追求...我放了两张截图,有点显示它发生了什么,以防你想看看。感谢您的尝试,但我不明白为什么有两个额外的桌子会在这里有所帮助。而且,如果我真的需要这样做,我可以在 SQL 中使用查询来做到这一点,除非我误解了你想要表达的意思 >.> 我对此进行了规范化,因为从数据的角度来看,您遇到了灾难。您正在创建一个应用程序,它只不过是一个试图在二维表中表示规范化数据的 excel 电子表格。您正在努力解决的是 Codd 博士创建关系数据库的原因。 @AlexSpencer 您可以在此表上创建一个 PIVOT 以在您的应用程序中显示它。当有人想更改结果网格中的某些字段时 - 你可以得到LastName
of trainer 和[date]
当然并将它们放入表TrainerCourses
。
@gofr1 实际上,现在我想一想,我所需要的只是能够在按下添加按钮时将新列添加到datagridview(或者在按下删除按钮时将其删除)然后仅在按下保存按钮时更新数据源 SQL 表。我认为这很简单,但显然不是。以上是关于将列从 DGV 添加到 SQL 服务器的问题的主要内容,如果未能解决你的问题,请参考以下文章