I know This is something simple yet I cannot do it right or find any answer searching google.
I want to update/edit the data. in the database server, by clicking the data that display on my DataGridView.
below is my sub Edit, the code is not automatically fetching the record to the textbox.
Private Sub btnEdit_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnEdit.Click
Dim transaction As SqlTransaction = Nothing
With New SqlConnection(connectionString)
Try
Call .Open()
transaction = .BeginTransaction()
With .CreateCommand()
.Transaction = transaction
.CommandText = "UPDATE [tbl_info] SET [Name]=#Name WHERE [ID]=#ID;"
With .Parameters
.AddWithValue("ID", txtID.Text)
.AddWithValue("Name", txtName.Text)
End With
Call .ExecuteNonQuery()
Call transaction.Commit()
Call MessageBox.Show("has been update successfully")
End With
Catch ex As Exception
Call transaction.Rollback()
Call MessageBox.Show(ex.Message, "Error")
Finally
Call .Close()
End Try
End With
RefreshData()
Call txtID.Clear()
Call txtName.Clear()
End Sub
On the ExecuteNonQuery line, capture the number of affected rows.
Dim rc As Integer = .ExecuteNonQuery()
If rc comes back as zero we can tell the query ran and found nothing to update.
Related
I am trying to insert data to database, but getting error as ExecuteNonQuery: Connection property has not been initialized.
Everything seems ok with the connection.
Imports System.Data.SqlClient
Public Class crud1
Private Sub Add_btn_Click(sender As Object, e As EventArgs) Handles Add_btn.Click
Try
Dim conn_ As New SqlConnection("Data Source=DESKTOP-VVM5A31;Initial Catalog=temp;Integrated Security=True")
conn_.Open()
Dim command As New SqlCommand("INSERT INTO STUDENT (student_name, student_age) VALUES (#NAME, #AGE)")
command.Parameters.AddWithValue("#NAME", TXT_NAME.Text)
command.Parameters.AddWithValue("#AGE", Convert.ToInt32(TXT_AGE.Text))
command.ExecuteNonQuery()
MsgBox("Record saved.", MsgBoxStyle.Information)
conn_.Close()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
End Class
Please see the image for the connection property.
You are right taking into account that the command needs the connection open, before execute the command, and you are doing right.
But you are not telling to the command which is the connection to be used.
An easy way to do it would be something like this, before execute the command:
command.Connection = conn_
*NOTE: I deleted my previous question "Update Database from DataTable and DataAdapter" in place of this one. I have updated the wording and code to be what I am currently testing.
I am trying to update a database with info from a WinForm. I had no issues when using a “normal” SQL update command written by hand (parameters set to the text box values,) but I am trying to clean up and reduce my code and I thought I would bind the controls to a DataTable and use a DataAdapter's update command to achieve the same thing.
I have tried to get various combinations of setting parameters and update commands to work, but the Database is not getting updated from the new DataTable values. I have stepped through the code with each change and can see that the DataTable is getting the new textbox values, but those updates aren’t going to the Database. (This is seen when the Fill_Date block runs and selects all new data from the database.)
Things I’ve tried: Letting the binding get the new values vs. setting the parameters manually. Using the command builder to build the update command, using the .UpdateCommand.ExecuteNonQuery(), command and of course a straight.Update(DataTable) command.
Below is the code that I am using. I am hoping someone can tell me what it is I am doing wrong/missing, or what is the correct path to take. Is there a "best practice" or a better way to do this?
Public Class frmDATA
Dim dt_Test As New DataTable
Dim da_Test As New SqlDataAdapter
Dim SQLcmd As SqlCommand
Private Sub frmDemog_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BuildSQL()
Fill_Data()
BindControls()
End Sub
Private Sub frmDemog_Closed(sender As Object, e As EventArgs) Handles Me.Closed
If Not IsNothing(dt_Test) Then dt_Test.Dispose()
If Not IsNothing(da_Test) Then da_Test.Dispose()
If Not IsNothing(SQLcmd) Then SQLcmd.Dispose()
Me.Dispose()
End Sub
Private Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
Update_Me()
End Sub
Private Sub BindControls()
txtLName.DataBindings.Add("Text", dt_Test, "Last_Name")
txtFName.DataBindings.Add("Text", dt_Test, "First_Name")
txtAKA.DataBindings.Add("Text", dt_Test, "AKA")
End Sub
Public Sub Update_Me(RefreshSearch As Boolean, RefreshView As Boolean)
Try
Dim testID As Integer = frmTest.dgvSearch.CurrentRow.Cells(0).Value
da_Test.UpdateCommand.Parameters("#ID").Value = testID
da_Test.Update(dt_Test)
Fill_Data()
Catch SqlExceptionErr As SqlException
MsgBox(SqlExceptionErr.Message, vbCritical, "Error")
Catch ex As Exception
MsgBox(ex.Message, vbCritical, "Error")
End Try
End Sub
Public Sub Fill_Data()
Try
dt_Test.Clear()
da_Test.SelectCommand.Parameters("#ID").Value = testID
da_Test.Fill(dt_Test)
Catch SqlExceptionErr As SqlException
MsgBox(SqlExceptionErr.Message, vbCritical, "Error")
Catch ex As Exception
MsgBox(ex.Message, vbCritical, "Error")
End Try
End Sub
Private Sub BuildSQL()
'** Build Selection Query
SQLcmd = New SqlCommand(String.Join(Environment.NewLine,
"SELECT ",
"data_Test.[Last_Name], ",
"data_Test.[First_Name], ",
"data_Test1.[Last_Name] + ', ' + data_Test1.[First_Name] as [AKA] ",
"FROM [DB].data_Test ",
"LEFT JOIN [DB].data_Test as data_Test1 ",
"ON data_Test.[ID] = data_Test1.[AKA_Demog_ID] ",
"WHERE data_Test.[ID]=#ID"
), Vars.sqlConnDB)
SQLcmd.Parameters.Add("#ID", SqlDbType.Int)
da_Test.SelectCommand = SQLcmd
'** Build Update Query
SQLcmd = New SqlCommand(String.Join(Environment.NewLine,
"UPDATE [DB].data_Test SET ",
"[Last_Name] = #LName,",
"[First_Name] = #FName",
"WHERE [ID] = #ID"
), Vars.sqlConnDB)
With SQLcmd.Parameters
.Add("#LName", SqlDbType.NVarChar, 255, "Last_Name") 'Required
.Add("#FName", SqlDbType.NVarChar, 255, "First_Name") 'Required
.Add("#ID", SqlDbType.Int, 0, "ID")
End With
da_Test.UpdateCommand = SQLcmd
End Sub
End Class
In my application I want the show the SQL Query progress. For example, assume a user clicked on a backup button, then I want him to be able to view the progress of the query he made in case the database is too big to restore or backup. At first I tried to do this by assuming how much disk space the database might take before even start backing up and then using that with the copying rate to estimate a time it might take to backup. But unfortunately I failed. Then by luck I found one lovely T-SQL command that show the stats when used in SSMS and it is just using an extra line 'With Stats = [Some integer] e.g. 1, 10, 20, etc' but here is the problem. I cannot find any work through for this to work with Vb.Net aka my application.
I found this awesome query from this link (www.mssqltips.com). If you open the website you can see few examples showing this.
The code to get stats:
Use dbName Backup dbName To Disk='BackupLocation' With STATS = 10
Edit #1:
Adding these lined of code now does showing the InfoMessage I was searching for but still not useful as this shows up only when the full operation is completed.
But what I want is to show them dynamically.
Code that worked:
AddHandler con.InfoMessage, New SqlInfoMessageEventHandler(AddressOf OnInfoMessage)
Private Sub OnInfoMessage(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlInfoMessageEventArgs)
strInfo.AppendLine(e.Message)
txtMsg.Text = strInfo.ToString
End Sub
My complete code:
Imports System.Data.Sql
Imports System.Data.SqlClient
Imports System.Text
Public Class BackupForm
Dim ConnectionString As String = My.Settings.LADBConnectionString
Dim con As SqlConnection = New SqlConnection(ConnectionString)
Dim cmd As New SqlCommand()
Private Sub btnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
Using OFD As New SaveFileDialog
With OFD
.FileName = "Backup " + Now.ToString("dd-MM-yyyy")
.Filter = "Log Application Backup |*.bak"
.CheckFileExists = False
.OverwritePrompt = False
Select Case .ShowDialog
Case DialogResult.OK
If .FileName <> "" Then
txtBackup.Text = .FileName
End If
End Select
End With
End Using
End Sub
Private Sub btnBackup_Click(sender As Object, e As EventArgs) Handles btnBackup.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Dim strInfo As New StringBuilder
Private Sub OnInfoMessage(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlInfoMessageEventArgs)
strInfo.AppendLine(e.Message)
txtMsg.Text = strInfo.ToString
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim backupQuery As String = $"use LDDB Backup database LDDB to Disk='{txtBackup.Text}' With STATS = 1"
Try
con.Open()
cmd.CommandType = CommandType.Text
cmd.CommandText = backupQuery
cmd.Connection = con
AddHandler con.InfoMessage, New SqlInfoMessageEventHandler(AddressOf OnInfoMessage)
cmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
con.Close()
con.Dispose()
End Try
End Sub
Private Sub BackupForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Control.CheckForIllegalCrossThreadCalls = False
End Sub
End Class
I have a conundrum.
In my VB.net program, in multiple places I communicate with my SQLserver database. I use Insert, Update and Select statements. My program is made up of multiple forms and my database has 4 tables.
All but one of my subs is working, and despite using break-points and walk through's of the code I can not figure out why.
The form and database tables in question are fine with the select and Insert statements are fully functioning, however the code of the update statement is not. When I run a walk through it behaves as if it has sent the data to the database, however the database never receives it. The connection data is identical to the functioning subs, and the code is in the same format as my update code in other forms within my program. So I can't see why its not working.
Here is the code:
Public selectedDeviceNumber As String = ""
Public selectedDeviceRowNumber As Integer = 0
'================================
'= Set up the DATASETS! =
'================================
Dim PCBconnectionstring As String = "Data Source=ServerName;Initial Catalog=Databasename;User Id=UserId;Password=password;Connect Timeout=30;User INstance=False"
Dim PCBsqlconnection As New SqlClient.SqlConnection(PCBconnectionstring)
Dim damyPCB As New SqlDataAdapter
Dim dsmyPCB As New DataSet
Dim ALcon As New SqlConnection
Dim ALcmd As New SqlCommand
Dim PCBcmd As New SqlCommand
Dim PCBcon As New SqlConnection
'================================
'= SAVE the data! =
'================================
Dim test As String = Me.selectedDeviceNumber
Private Sub SaveToDataBaseFunctionPCB()
'update the data entered to the database
Try
PCBsqlconnection.ConnectionString = "Data Source=ITWIN10-PC\SQL2010;Initial Catalog=SLE1000;User Id=UserId;Password=password;Connect Timeout=30;User Instance=False"
PCBsqlconnection.Open()
PCBcmd.Connection = PCBsqlconnection
PCBcmd.CommandText = "UPDATE PCBlist SET pcbSerial=#pcbSerial,pcbPart=#pcbPart,pcbVent=#pcbVent,pcbDesc=#pcbDesc," & _
"pcbTested=#pcbTested,pcbU1=#pcbU1,pcbU5=#pcbU5,pcbU7=#pcbU7,pcbU10=#pcbU10,pcbU11=#pcbU11,pcbVersion=#pcbVersion," & _
"pcbTestIni=#pcbTestIni,pcbApplyIni=#pcbApplyIni,pcbTestDate=#pcbTestDate,pcbApplyDate=#pcbApplyDate WHERE pcbID=#pcbID "
PCBcmd.Parameters.AddWithValue("#pcbSerial", txtSerialPCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbPart", cboPartPCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbVent", txtVentPCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbDesc", txtDescriptPCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbTested", chkTested1.Checked)
PCBcmd.Parameters.AddWithValue("#pcbU1", txtU11.Text)
PCBcmd.Parameters.AddWithValue("#pcbU5", txtU51.Text)
PCBcmd.Parameters.AddWithValue("#pcbU7", txtU71.Text)
PCBcmd.Parameters.AddWithValue("#pcbU10", txtU101.Text)
PCBcmd.Parameters.AddWithValue("#pcbU11", txtU111.Text)
PCBcmd.Parameters.AddWithValue("#pcbVersion", txtVersionPCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbTestIni", txtTestPCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbApplyIni", txtApplyPCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbTestDate", txtTestDatePCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbApplyDate", txtApplyDatePCB1.Text)
PCBcmd.Parameters.AddWithValue("#pcbID", Me.selectedDeviceNumber)
PCBcmd.ExecuteNonQuery()
PCBcmd.Parameters.Clear()
PCBsqlconnection.Close()
MsgBox("Data updated")
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
PCBsqlconnection.Close()
End Try
End Sub
`Private Sub btnAmend_Click(sender As System.Object, e As System.EventArgs) Handles btnAmend.Click
'Save the data to SQL Server
SaveToDataBaseFunctionPCB()
'record activity in Activity Log
FrmSLE1000.txtActivityLogRecorder.Text = ("Data Saved")
'Save the Activity log data to SQL Server
SaveToDataBaseFunction1()
'SLE1000SqlConnection = New SqlConnection(frmConnections.lblDBConnection.Text & frmConnections.lblDBConnection2.Text)
End Sub
If you have any ideas then please let me know. It could be that I've been looking at the code too long and its obvious, however I can't see the problem.
Many thanks
After extensive fiddling with my code I have fixed the problem. As it turns out the problem lay further back in the code. When the Select statement was called it loaded the data into a list view, which you then select a row which you want to edit. The catch ex as exception was being fired at this point, however the data was still being passed to the text boxes so that you could edit the data, so I mentally 'parked' that glitch for later. In solving that glitch the "amend" button and Update function works fine.
If you're interested the original glitch in the code was as follows
Private Sub lvPCB1_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lvPCB1.DoubleClick
Dim newmachine As String = FrmSLE1000.txtNo.Text
Try
If lvPCB1.SelectedItems.Count = 0 Then
MessageBox.Show("Ensure that you have selected a PCB Board. Try again.")
Exit Sub
Else
'Set selected units ID number in varable to allow access to all row data to populate tables
selectedDeviceNumber = lvPCB1.SelectedItems(0).Text
PopulateTablesFunctionPCB()
txtSerialPCB1.Text = lvPCB1.SelectedItems(1).Text
'record activity in Activity Log
End If
Catch ex As Exception
MessageBox.Show("Problem with selection")
End Try
End Sub
and the new working code is as follows
Private Sub lvPCB1_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lvPCB1.DoubleClick
Dim newmachine As String = FrmSLE1000.txtNo.Text
Try
If lvPCB1.SelectedItems.Count = 0 Then
MessageBox.Show("Ensure that you have selected a PCB Board. Try again.")
Exit Sub
Else
'Set selected units ID number in varable to allow access to all row data to populate tables
selectedDeviceNumber = lvPCB1.SelectedItems(0).Text
PopulateTablesFunctionPCB()
txtSerialPCB1.Text = lvPCB1.SelectedItems(0).Text
'record activity in Activity Log
End If
Catch ex As Exception
MessageBox.Show("Problem with selection")
End Try
End Sub
So it all came down to having a "1" instead of a "0" in the line "txtSerialPCB1.Text = lvPCB1.SelectedItems(0).Text"
And there you have it!
I'm having a bit of an issue with my code. I have connected the database and am able to view records, add records and even delete records.
However, I cannot get the update button working at all. I keep getting an "InvalidOperationException" error.
Private Sub btnAmend_Click(sender As System.Object, e As System.EventArgs) Handles btnAmend.Click
Dim cb As New OleDb.OleDbCommandBuilder(da)
ds.Tables("Contacts").Rows(inc).Item(1) = txtFirstName.Text
ds.Tables("Contacts").Rows(inc).Item(2) = txtSurname.Text
da.Update(ds, "Contacts")
MsgBox("Data updated")
End Sub