2016-06-09 4 views
2

Прошу прощения, если заголовок немного расплывчатый, но я не был уверен, как положить его в короткое пространство.Проблемы с добавлением столбца с DGV на SQL-сервер

Для контекста у меня есть кнопка сохранения, когда изменения внесены в базу данных SQL-сервера. Это отлично работает при добавлении строк или изменении значений даже при удалении строк. Там ничего плохого.

Однако, когда я пытаюсь добавить или удалить столбцы, приложение становится немного более проблематичным и просто не обновляет добавленные/удаленные столбцы в базе данных и не выдает ошибку.

Единственный способ, которым я могу добавлять или удалять столбцы для работы, - это использовать 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 

Извините, если это было немного долго наматывается, но ... я не могу найти способ, чтобы добавить столбцы в базе данных достаточно, как я тоже хотел, ни через прибегая к помощи ответа, ни через простые эксперименты, поэтому я пришел сюда в надежде, что один из вас сможет помочь. Заранее благодарим за любую помощь, которую вы можете предоставить.

EDIT --- Я использую oleDB как соединение с sql, если это помогает.

EDIT 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"

EDIT 3 --- Хорошо, я знаю, нормализующие таблицы вещь, что Шон был на около мог работать, но это, возможно, потребуется довольно большое изменение сервера, используемого и к программе. Мне удалось найти более простой способ получить эту работу, которая вызывает sql-запросы для добавления или удаления столбцов в таблицу сохранения, только после того, как изменения были внесены в сетку данных.

Имеет некоторый код в случае, если кто-либо заинтересован. Это немного грязно и, вероятно, может быть оптимизировано немного, но это работает для меня независимо. `Private Function 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` 
+0

Какая ошибка возникает из-за 'ALTER TABLE ...'? – gofr1

+0

Thats the thing. Во время этого я не получаю сообщение об ошибке. Проблема больше связана с тем, что использование SQL-запроса выполняется при запуске функций добавления или удаления, когда в это время я хочу, чтобы он отображался в виде сетки данных. Я хочу, чтобы столбцы были добавлены или удалены из базы данных SQL Server после того, как я нажал кнопку «Сохранить» (которая, очевидно, запускает функцию сохранения) –

+0

Знаю, что я забыл что-то упомянуть - я использую oleDB для моего подключения к SQL , эта команда, по-видимому, не является членом oleDB. –

ответ

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) 
) 
+0

Я не уверен, что объяснил, что я очень хорошо с ним сделал ... Я поставил два скриншота, которые показывают, что происходит с ним, если вы хотите посмотреть. Спасибо за попытку, но я не понимаю, почему здесь могут помочь две дополнительные таблицы. И, если мне действительно нужно было это сделать, я мог бы сделать это из SQL с помощью запросов, если я не понял, что вы пытаетесь передать>.> –

+1

Я нормализовал это, потому что у вас есть катастрофа с точки зрения данных. Вы создаете приложение, которое представляет собой не что иное, как таблицу Excel, которая пытается представить нормализованные данные в двумерной таблице. То, с чем вы боретесь, связано с тем, что реляционные базы данных были созданы д-ром Коддом. –

+0

@AlexSpencer вы можете сделать PIVOT в этих таблицах, чтобы показать его в своем приложении. Когда кто-то хочет изменить какое-то поле в сетке результатов - вы можете, конечно, получить «LastName» тренера и «[даты]» и поместить их в таблицу «TrainerCourses». – gofr1