Updating row in database using vb.net - vb.net

I am trying to update and save a row of a database table. I have used a version of this code to just populate a GridView and it works, so I am assuming it has something to do with my SQL statment; I do not get an error, the table just does not update. On the page load event I have the textboxes being populated by the information of the row, and I have a global variable, named 'temp', that will save the title of the row so I can use it in the button's click event. The error I am getting states that I have not given a value for one of my required parameters. My Locals tab on the debugger shows that every variable has a value, though the one I try to update is not the new data but still the old data.
I have looked at several examples and I cannot find the problem though. Thank you for any assistance.
Protected Sub btnSave_Click(sender As Object, e As EventArgs)
Dim strTitle As String = txtTitle.Text
Dim strConsole As String = txtConsole.Text
Dim strYear As String= txtYear.Text
Dim strPurchase As String = calDate.SelectedDate.ToString
Using con As OleDbConnection = New OleDbConnection("PROVIDER=Microsoft.ACE.OLEDB.12.0;" + "DATA SOURCE=" + Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "App_Data", "db1.accdb"))
Dim cmd As OleDbCommand = New OleDbCommand()
cmd.CommandText = Convert.ToString("UPDATE Video_Games SET Title = #title, Console = #Console, Year_Released = #Year_Released, Purchase = #Purchase WHERE Title=" & temp)
cmd.Connection = con
cmd.Parameters.AddWithValue("#Title", strTitle)
cmd.Parameters.AddWithValue("#Console", strConsole)
cmd.Parameters.AddWithValue("#Year_Released", strYear)
cmd.Parameters.AddWithValue("#Purchase", strPurchase)
con.Open()
cmd.ExecuteNonQuery()
con.Close()
End Using
Server.Transfer("Form.aspx", True)
End Sub
I have also tried the have my where statement as: WHERE Title='" & temp & "'") Though this does not work either.
This is the details of the Error message

I changed you commandText as seen below and created a blank database with a table named just like yours and the update worked
cmd.CommandText = "UPDATE Video_Games SET Title = #title, Console = #Console, Year_Released = #Year_Released, Purchase = #Purchase WHERE Title='" & temp & "'"
I set my variable for Title = Super Mario Bros and then the temp variable to Wario World. I had a record in my database with the title of Wario World, and running the update changed the title to Super Mario Bros.
Check if you temp variable is different from your #title variable. Also check that you have the record int the table for your temp variable title

Thank you all for your assistance, This is such a wonderful community.
The problem, I found out, does not even have to do with the button's click event, it had to do with the page load event. Since on page load the row's information is loaded and populated into the textboxes, when the button is clicked to update the fields, the page load event triggers again and reloads the old information into fields, essentially saving the old information instead of the new. My fix was to create an If Not IsPostBack Then statement that encapsulates my on page load code. Therefore the code does not get saved when the button is pressed. Another this, I did not need the temp variable, using WHERE Title='" + strTitle + "'" worked. Hopefully this helps other people stuck on a similar problem!

Using dates in a where clause is always ify as they are floating point numbers and may not match equally. I'd try and round them or convert them to strings before comparison, e.g. something along these lines:
UPDATE Video_Games SET Title = #title, Console = #Console, Year_Released = #Year_Released, Format(Purchase, ""m/d/yyyy"") = Format(#Purchase, ""m/d/yyyy"") WHERE Title = #Title

Related

"NotOnList" event not recognizing that new data has, in fact, been added

This used to work but now it doesn't. Did Microsoft change something?
I'm attempting to understand the behavior of a combo box in MS Access. I created a table named "Colors" with 2 fields: ID (Autonumber, primary key) and Color (short text). I made a form with a combobox with "LimitToList" set to Yes. The Row Source is the table "Colors". For the NotInList event I have the following code:
Private Sub Colors_NotInList(NewData As String, Response As Integer)
Dim rst As DAO.Recordset
If MsgBox(NewData & " is not in list. Add it?", vbOKCancel) = vbOK Then
Response = acDataErrAdded
Set rst = CurrentDb.OpenRecordset("Colors")
With rst
.AddNew
!Color = NewData
.Update
End With
Else
Response = acDataErrContinue
ctl.Undo
End If
End Sub
If I enter a color not in the table I get the prompt to add it to the list. On clicking OK I get the Access error that I must select an item on the list. The new color I just entered does appear on the list and if I select it everything works fine. But I didn't used to have this second step of selecting it after it's been entered.
I've spent way to much time on what should be a simple task. Can anyone help? Thanks!

TableAdapter data has changed but property "has Changes" stays at "false" so udate does nothing

It's mostly in the title...
I'm using VB (obviously, see below), but I'm a total beginner with visual studio.
Here is the test code I'm using (it is a simple test button I designed to test the problem I have in the code elsewhere):
Private Sub Test_Click(sender As Object, e As EventArgs) Handles Test.Click
Dim FDBdataset As New FDBDataSet()
Dim FDBTableAdapter As New FDBDataSetTableAdapters.T_PicturesTableAdapter
For Each row As DataRow In FDBTableAdapter.GetData()
row.BeginEdit()
If row("id").ToString = 58672.ToString Then
row.BeginEdit()
Console.Write("Previous Value = " & row("ImgFileName").ToString)
row("ImgFileName") = "Tagada"
row.EndEdit()
Console.WriteLine(", Current Row Value = " & row("ImgFileName").ToString & " - HasChanges : " & FDBdataset.HasChanges())
End If
Next
FDBTableAdapter.Update(FDBdataset)
The output in the console is:
Previous Value = Aphidecta_obliterata_58672, Current Row Value = Tagada - HasChanges : False
I don't understand what is wrong and how to correct it...
I would be very grateful for some help here !
TableAdapter seems set up correctly, and I can read from it, parse rows; display field values, etc...
Update method reports as being correctly set up by the datasource designer.
Code runs without errors but does not affect the DB content.
Why would you think that FDBdataset has any changes in it? Where are you making any changes to it? You have this:
For Each row As DataRow In FDBTableAdapter.GetData()
and GetData returns a new DataTable, so you're making change to that DataTable completely independent of FDBdataset. Use one or the other but not both.
Based on the code you have there, you don't need the DataSet. You can just use the DataTable returnd by GetData:
Dim adapter As New FDBDataSetTableAdapters.T_PicturesTableAdapter
Dim table = FDBTableAdapter.GetData()
For Each row In table
If row.id = 58672 Then
row.ImgFileName = "Tagada"
End If
Next
adapter.Update(table)
Notice that I tidied up your code a lot too. If you're going to use a typed DataSet then use it.
If you actually do need a DataSet for some reason then make the changes to it, not an unrelated DataTable:
Dim data As New FDBDataSet
Dim adapter As New FDBDataSetTableAdapters.T_PicturesTableAdapter
adapter.Fill(data)
For Each row In data.T_Pictures
If row.id = 58672 Then
row.ImgFileName = "Tagada"
End If
Next
adapter.Update(data)
That second code snippet may need some adjustments but I think it should work.
So, the moral of the story is that the Fill method populates an existing DataTable, which can be part of a DataSet but doesn't have to be, while the GetData method creates a new DataTable, populates it and returns it. That new DataTable is not part of any DataSet.

Datagridview - proper wat of doing Updating/Inserting

I'm doing this for first time and I need some guidance. I have Datagridviews set to It's datasource. Now how do I properly Update or Insert records to DB from It?
My questions:
Currently I dont have any buttons under Datagridviews (like Add/Remove/Update - do I need them without doubt or is It possible to handle all actions without them ? - I don't use TableAdapterManager !)
MERGE statement - can It be used to compare certain Table with Datagridview and perform Update or Insert on same Table?
If doing INSERT or UPDATE manually, what goes first and how to check what must be done ?
I allready have a code for doing both, but It doesn't work as It should, problem is that I have only 1 button for saving data on form - and that button should Insert or Update data in DB from 2 Datagridviews + Databinded Textboxes on form. So basically there are 3 Tables that can be Updated/Inserted on same form - Datagridviews show related data and Databinded Texboxes show master Table record.
Any help much appreciated.
EDIT (here is my complete code - first loading data into form and Datagrid, then code for Btn_Save):
Imports System.Data
Imports Oracle.DataAccess.Client ' ODP.NET Oracle managed provider
Imports Oracle.DataAccess.Types
Imports System.IO
Imports System
Imports System.Windows.Forms
Imports System.ComponentModel
Public Class Form2
Private da, da1 As OracleDataAdapter
Private cb, cb1 As OracleCommandBuilder
Private ds, ds1 As DataSet
Public OpenedForm1 As Form1 'required for obtaining record ID - this form opens when user double clicks on datagridview record
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BtnSave.Enabled = False 'for eliminating errors when using dataset Update (Oracle recommendation)
Dim SQL1 As String = "SELECT * from TABLE1 WHERE ID_Table1=" & OpenedForm1.DataGridView1.CurrentRow.Cells(0).Value.ToString
Dim DGV1_SQL As String = "SELECT ID_TABLE2, ID_TABLE1, Name, Surname, WHERE ID_TABLE1=" & OpenedForm1.DataGridView1.CurrentRow.Cells(0).Value.ToString
Dim DGV2_SQL As String = "SELECT TABLE3.SERIAL, TABLE3.MODEL," _
& " TABLE3.TYPE FROM TABLE3 INNER JOIN (TABLE1 INNER JOIN TABLE1_TABLE3 ON TABLE1.ID_Table1=TABLE1_TABLE3.ID_Table1_FK) ON " _
& "TABLE3.ID_Table3=TABLE1_TABLE3.ID_Table3_FK WHERE TABLE1_TABLE3.ID_TABLE1_FKK=" & Openedform1.DataGridView1.CurrentRow.Cells(0).Value.ToString
Try
Oracleconn()
'Then I do all DB queries and display results on form
'For SQL1 Databind all textboxes – this is a master record on form
'For DGV2_SQL and DGV2_SQL fill datasets and set Datagrids to datasource
'I'm also hiding all primary key fields and bounding datagrids to Binding sources to enable Binding navigators under them.
End Sub
Private Sub BtnSave_Click(sender As Object, e As EventArgs) Handles BtnSave.Click
'First I assign some variables for Oracle parameters, such as dealing with Null Date values
Oracleconn() 'My connection to DB
Using cmd As OracleCommand = New OracleCommand()
cmd.Connection = Oracleconn()
cmd.Parameters.Clear()
'Adding a lot of paramters here for master record like this...
cmd.Parameters.Add(New OracleParameter("ID", TxtID.Text))
))
'Only Update for master record – Textboxes on form – works just fine
cmd.CommandText = "UPDATE TABLE1" _
& " SET ID_TABLE1= : id .etc
If Not (TxtSerial.Text = "" Or TxtInventar.Text = "11111" Or TxtInventar.TextLength < 9) Then
cmd.ExecuteNonQuery()
cmd.Parameters.Clear()
'Then checking 1st datagridview for data in It
For Each row As DataGridViewRow In DGV1.Rows
If row.Cells(1).Value <> Nothing Then
'Adding parameters again
'Then my attempt for doing update or Insert with MERGE – doesn't work
cmd.CommandText = "MERGE INTO TABLE2 v" _
& "USING (SELECT * FROM TABLE2 WHERE ID_TABLE2='" & row.Cells(1).Value & "') u" _
& " ON u.ID_TABLE2" _
& " WHEN MATCHED THEN UPDATE SET all fields except ID's " _
' & " WHEN NOT MATCHED BY v" _
' & " THEN INSERT... all fields" _
' & " VALUES.... from parameters"
cmd.ExecuteNonQuery()
cmd.Parameters.Clear()
'This was used before, but ofcourse It only updates
da.Update(ds.Tables(0))
BtnSave.Enabled = True
Else
MsgBox("You cannot save without 1st field empty !")
Exit For
End If
Next
'Then check for next Datagrid – this one is hard, It's a joined Table(entitity) from Table1 and Table3, with showing data from that joined Table too
For Each row As DataGridViewRow In DGV2.Rows
'Adding parameters and just performing update – didn't start the Insert so far
MsgBox("Saved.", MsgBoxStyle.Information, "Editing records")
'Refresh Datagridview in Form1 - which is also opened
OpenedForm1.BtnSearch()
Else
MsgBox("1st field is required to be filled If you want to save.", MsgBoxStyle.Exclamation, "Editing records")
End If
End Using
OracleClose() 'close my connection
End Sub
You basically need to do inserts first, then updates, then deletes. You must insert parents before children and, unless your foreign keys cascade deletes, delete children before parents. For updates, it doesn't matter the order. E.g.
Dim parentAdapter As SqlDataAdapter
Dim childAdapter As SqlDataAdapter
Dim data As DataSet
Dim parentTable As DataTable
Dim childTable As DataTable
'...
Dim parentInserts = parentTable.GetChanges(DataRowState.Added)
Dim parentUpdates = parentTable.GetChanges(DataRowState.Modified)
Dim parentDeletes = parentTable.GetChanges(DataRowState.Deleted)
Dim childInserts = childTable.GetChanges(DataRowState.Added)
Dim childUpdates = childTable.GetChanges(DataRowState.Modified)
Dim childDeletes = childTable.GetChanges(DataRowState.Deleted)
If parentInserts IsNot Nothing Then
parentAdapter.Update(parentInserts)
End If
If childInserts IsNot Nothing Then
childAdapter.Update(childInserts)
End If
If parentUpdates IsNot Nothing Then
parentAdapter.Update(parentUpdates)
End If
If childUpdates IsNot Nothing Then
childAdapter.Update(childUpdates)
End If
If childDeletes IsNot Nothing Then
childAdapter.Update(childDeletes)
End If
If parentDeletes IsNot Nothing Then
parentAdapter.Update(parentDeletes)
End If
data.AcceptChanges()
Let Me answer you to the best and honest way as I can because honestly I did that before.
I will answer based on what I used Prog. Lang. and Database and Luckily VB.Net is my Language and MySQL is the database.
My Answers: (Order by your question)
1.Your asking if you need them? For me Yes! because i did that, Think of a form with a DatagridView (Populated with Data) and 3 Buttons (Add,Update,Delete)
Button: Add will save all your datagridview data in table. You see some link or tutorials here
Button: Edit will update specific data based on what you selected you can see it here. What I did is transfer them to textboxes and do the update.
Button: Delete will delete the data based on your selected row actully the link from button update will be your guide you will just edit it and the Delete Query
2.10000% YES! see this the output of that is to put color in datagridview if both of them are the same. (Sounds exiting? Love it :D)
3.Doing manualy would be hard for me so my tip here is why dont you edit your datagridview then do the Update Command Datagridview is editable but Pls provide atleast 1 column that will not be updated because it is the basis of your where clause
So there you go I said everything I know and it will depend on you on what you should follow so good luck and happy coding
Remember : Theres no wrong in coding One Output Tons of ways to execute

VB.Net affect changes to a table

I am using a datagridview to display table data and changing values of a particular cell. Depending on requirement I may need to change such values for more than one row.
I am trying to use datagridview1.CellValueChanged to populate a Dataset (i.e. create a collection of changes made) and subsequently saving the changes by clicking on a command button.
My problem is that though for each change, the sub is being called ONLY the last change is being saved. I was thinking of using the Dataset to store multiple records where the values are changed and then SAVE all the rows in the Dataset in the database table (using Update).
Could there be some solution to my predicament.
PS. Before trying this (ADO.net dataset) I was updating a temporary table and then using that I was updating the database.
Grateful for a solution please.
Code:::
Private Sub dGridVwCreaCode_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dGridVwCreaCode.CellValueChanged
Dim qryStr_CodeShtText_Changed As String
Dim var_CodeID_Changed As Long
var_CodeID_Changed = dGridVwCreaCode(e.ColumnIndex - 2, e.RowIndex).Value
qryStr_CodeShtText_Changed = "SELECT Code_ID, Code, Code_Descrip FROM Code_SAP " & _
"WHERE (Code_SAP.Code_ID = " & var_CodeID_Changed & ")"
var_CodeShtText_Changed = dGridVwCreaCode(e.ColumnIndex, e.RowIndex).Value.ToString
If Not CatGenieConnPublic.State = ConnectionState.Open Then
CatGenieConnPublic.Open()
End If
da_CodeShtText_Changed = New OleDb.OleDbDataAdapter(qryStr_CodeShtText_Changed, CatGenieConnPublic)
da_CodeShtText_Changed.Fill(ds_CodeShtText_Changed, "Code_SAP")
cb_CodeShtText_changed = New OleDb.OleDbCommandBuilder(da_CodeShtText_Changed)
ds_CodeShtText_Changed.Tables("Code_SAP").Rows(1).Item("Code_Descrip") = var_CodeShtText_Changed
To save the changes (following sub being called from a Button_Click):
Private Sub Save_Changed_CodeShtText()
da_CodeShtText_Changed.Update(ds_CodeShtText_Changed, "Code_SAP")
MsgBox("Changes saved to database....", vbOKOnly + vbInformation)
If CatGenieConnPublic.State = ConnectionState.Open Then
CatGenieConnPublic.Close()
End If
'SET BOOLEAN TO FALSE AS CHANGED VALUES HAVE BEEN SAVED
bool_CellVal_HasChanged = False
End Sub
PS. Somehow I am not able to place all the code lines together, pl pardon me.
What I was missing out on was incrementing the "row" count in the code line:
ds_CodeShtText_Changed.Tables("Code_SAP").Rows(rowNum_Increment - 1).Item("Code_Descrip") = var_CodeShtText_Changed
So every time the user changes data in the particular cell, rows number in incremented by "1" and is collected in the dataset.

Print in VB.NET 2010

I want to print on a Passbook (paper book used to record bank transactions) using a passbook printer (Epson PLQ 20) Using VB.NET 2010.
My current mysql table structure is,
1. tblLoanRegistry(LoanID pk, EMPNumber, Date, Amount, NoOfInstallments, Teller)
2. tblLoanAccount(ID pk, LoanID fk, Date, Payment, Interest, Total, Auto bool, Installment int, teller)
My problems are:
How to detect the last row printed?
How to print the first row that not printed, on the correct position of the book (Correct line).
I have decided to add a field "Printed" (Boolean) in each table above mentioned. To get the printed or not. I can print text, numbers etc using the same printer in vb.net (Eg: Account holders details on the front page). But I'm facing above mentioned problems when printing transactions. Your help/ opinions highly appreciated.
More Information:
Actually I developed a web based account handling system using php and mysql for a non profit organisation as the my project of the degree. Now they want to print transactions on a passbook as I described before.
Therefore I am creating an application using VB.NET (I am totally new to VB.NET. But have experience in vb6) while I am learning it. I have managed to simple printing but this is something different.
I have no good idea to solve above mentioned two problems.
Update:
I did it in different (may be a bad) way.
On click event of the print button.
Dim sqlLoan As String
conn = New MySqlConnection(cnString)
sqlLoan = "SELECT tblLoanAccount.Date,if(Installment = 0, 'Interest', concat('Installment : ', Installment)) as Description, tblLoanAccount.Payment, tblLoanAccount.Interest, " &
" tblLoanAccount.Total, tblLoanAccount.Auto, tblLoanAccount.Installment FROM tblLoanAccount join tblloanRegistry on tblloanRegistry.LoanID = tblLoanAccount.LoanID " &
" where(tblloanRegistry.EMPNumber = " & cmbEMPN.Text & " And tblLoanAccount.LoanID = tblLoanRegistry.LoanID) AND tblLoanAccount.Total <> 0 ORDER BY tblLoanAccount.ID"
Using conn As New MySqlConnection(cnString)
Using cmd As New MySqlCommand(sqlLoan, conn)
conn.Open()
Using myReader As MySqlDataReader = cmd.ExecuteReader()
Using writer As StreamWriter = New StreamWriter("c:\file.txt")
While myReader.Read()
writer.WriteLine("{0}, {1}, {2}, {3}, {4}", myReader.Item(0), myReader.Item(1), myReader.Item(2), myReader.Item(3), myReader.Item(4))
End While
End Using
Call Printing()
End Using
End Using
End Using
' Print the file.
Public Sub Printing()
Try
streamToPrint = New StreamReader(("c:\file.txt"))
Try
printFont = New Font("Arial", 10)
Dim pd As New PrintDocument()
AddHandler pd.PrintPage, AddressOf pd_PrintPage
' Print the document.
pd.Print()
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub 'Printing
And other codes are as msdn PrintDocument Class.
There are a lot of unknowns in this question. For example, when you mark an item as printed, do you want to mark it universally (for all applications, all transactions and all time) or only within a limited context (a particular application, transaction or time frame)?
Is a transaction started and completed within a single .NET thread, or is this application multi-threaded, or does the transaction span across multiple independent executions? Do you need some record of an item having been printed beyond the physical piece of paper?
Assuming you want a record of an item having been printed only within a particular transaction, you may want to create a third table, called something like tblPrintTransaction, with a Primary Key or other identifier column and any additional columns you desire (transaction start date, end date, user ID, contextual information, etc.). When you start your application, create a new row in this table and get the row ID.
Now, create a fourth table, called something like tblPrintTransactionArtifact, with at least two columns. One column will be a foreign key identifying the transaction (from the tblPrintTransaction table) and one or more columns will be used to identify the item that has been printed. For example, your table could contain two columns to identify the printed item: one column specifying either "Registry" or "Account" and another specifying the item's ID.
Of course, all of this information could be created and maintained within the application itself (using variables, etc), but storing them in a table means they will persist beyond the execution of the application, giving you a permanent record. I would recommend that you keep track of the current "line" on the printed page within the application as I see little use for this within your database.
Dim sqlLoan As String
conn = New MySqlConnection(cnString)
sqlLoan = "SELECT tblLoanAccount.Date,if(Installment = 0, 'Interest', concat('Installment : ', Installment)) as Description, tblLoanAccount.Payment, tblLoanAccount.Interest, " &
" tblLoanAccount.Total, tblLoanAccount.Auto, tblLoanAccount.Installment FROM tblLoanAccount join tblloanRegistry on tblloanRegistry.LoanID = tblLoanAccount.LoanID " &
" where(tblloanRegistry.EMPNumber = " & cmbEMPN.Text & " And tblLoanAccount.LoanID = tblLoanRegistry.LoanID) AND tblLoanAccount.Total <> 0 ORDER BY tblLoanAccount.ID"
Using conn As New MySqlConnection(cnString)
Using cmd As New MySqlCommand(sqlLoan, conn)
conn.Open()
Using myReader As MySqlDataReader = cmd.ExecuteReader()
Using writer As StreamWriter = New StreamWriter("c:\file.txt")
While myReader.Read()
writer.WriteLine("{0}, {1}, {2}, {3}, {4}", myReader.Item(0), myReader.Item(1), myReader.Item(2), myReader.Item(3), myReader.Item(4))
End While
End Using
Call Printing()
End Using
End Using
End Using
' Print the file.
Public Sub Printing()
Try
streamToPrint = New StreamReader("c:\file.txt")
Try
printFont = New Font("Arial", 10)
Dim pd As New PrintDocument()
AddHandler pd.PrintPage, AddressOf pd_PrintPage
' Print the document.
pd.Print()
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub 'Printing
And other codes are as msdn PrintDocument Class.
You can try to use the easy to use, lightweight report writer I use with MySql & VB.Net at http://www.jcl.vdtec.net