Update database with dataviewgrid on joined query - sql

Update my SQL Server with info provided by dataviewgrid changes, mainly a checkbox / bit field.
I can populate my dataviewgrid and I can even make it update if i only use a single table, the problem is I want my query to have three tables joined, just to display information.
I've tried to replicate some tutorials and make changes of my own but it just doesn't seems to click.
It has been a while since I've coded in VB so there's also that.
What I have so far:
Imports System.Data.SqlClient
Public Class Form1
Dim myDA1 As SqlDataAdapter
Dim myDataSet1 As DataSet
Dim myDA2 As SqlDataAdapter
Dim myDataSet2 As DataSet
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim con2 As SqlConnection = New SqlConnection("Data Source=CONNECTION STRING WORKS FINE")
Dim cmd2 As SqlCommand = New SqlCommand("SELECT x1,y2,z1 from a inner join b where a.x1=b.x2", con2)
con2.Open()
myDA2 = New SqlDataAdapter(cmd2)
Dim builder2 As SqlCommandBuilder = New SqlCommandBuilder(myDA2)
myDataSet2 = New DataSet()
myDA2.Fill(myDataSet2, "MyTable2")
DataGridView2.DataSource = myDataSet2.Tables("MyTable2").DefaultView
con2.Close()
con2 = Nothing
End Sub
Private Sub DataGridView2_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView2.CellContentClick
Me.Validate()
Me.myDA2.Update(Me.myDataSet2.Tables("MyTable2"))
Me.myDataSet2.AcceptChanges()
End Sub
End Class
It's updating on a basic query, yes, but i need to make it update on a join query.

As I said in my comment you cannot use a CommandBuilder when you use a join. You need to supply your own Update, Insert, and Delete commands for the DataAdapter. Be sure to use the overload of the Parameters.Add method that includes the name of the source column. This provides the mapping for the DataAdapter. I used a database on my machine to show the code. You would probably want to add commands for Insert and Delete.
Private da As SqlDataAdapter
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
da = New SqlDataAdapter
Dim dt As New DataTable
Dim query = "Select Article.ArticleID, Article.Title, Author.LastName From Article Inner Join Author on Article.AuthorID = Author.AuthorID"
Using cn As New SqlConnection(My.Settings.PublishersConnection)
Using cmd As New SqlCommand(query, cn)
da.SelectCommand = cmd
da.Fill(dt)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim Uquery = "Update Article Set Title = #Title Where ArticleID = #ID;"
Dim dt As DataTable = CType(DataGridView1.DataSource, DataTable)
Using cn As New SqlConnection(My.Settings.PublishersConnection)
Using UCommand As New SqlCommand(Uquery, cn)
UCommand.Parameters.Add("#Title", SqlDbType.VarChar, 50, "Title")
UCommand.Parameters.Add("#ID", SqlDbType.Int, 4, "ArticleID")
da.UpdateCommand = UCommand
da.Update(dt)
End Using
End Using
End Sub

Related

Insert, Delete, and Edit Data in DataGridView using single Update Button in Vb.net

I am trying to have a add, delete, and edit function in Vb.net by using one update button and changing the values in the datagridview manually then hitting update. However, I get an error stating
"System.InvalidOperationException: 'Update requires a valid UpdateCommand when passed DataRow collection with modified"
Any Ideas? The error comes next to the da.Update(changes)
Also in the above code not shown in my code I have load_data() in the private form1_load sub.
Here is code:
Dim da As New SqlDataAdapter
Dim dt As New DataSet
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim cmd As New SqlCommandBuilder
Dim changes As New DataSet
changes = dt.GetChanges
If changes IsNot Nothing Then
da.Update(changes)
da.Fill(dt)
DataGridView1.DataSource = dt.Tables(0)
End If
End Sub
Private Sub load_data()
Using connection = New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=vbconnectionfinal;Integrated Security=True")
da = New SqlDataAdapter("Select * From TrueTrack", connection)
dt.Clear()
da.Fill(dt)
DataGridView1.DataSource = dt.Tables(0)
End Using
End Sub
You are creating a SqlCommandBuilder but not associating it with a SqlDataAdapter, so what's the point? The whole purpose of a command builder is to automatically generate action commands when you call Update on a data adapter. When you create your data adapter, create the command builder immediately after and associate the two, which you would do by passing the data adapter as an argument to the constructor of the command builder.
The following code works for me.
Dim da As New SqlDataAdapter
Dim dt As New DataSet
Dim connection = New SqlConnection("connection string")
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim cmd As New SqlCommandBuilder(da)
Dim changes As New DataSet
changes = dt.GetChanges
If changes IsNot Nothing Then
da.Update(changes)
DataGridView1.DataSource = dt.Tables(0)
End If
End Sub
Private Sub load_data()
Dim cmd As SqlCommand = New SqlCommand("Select * From TrueTrack", connection)
da = New SqlDataAdapter(cmd)
dt.Clear()
da.Fill(dt)
DataGridView1.DataSource = dt.Tables(0)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
load_data()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
connection.Close()
End Sub

VB.Net OleDBConnection code to update access database from DataGridView

I have a simple userform with a DataGridView and I would like to use OleDB code to update the accdb database based on any entries made in the gridview. The load button works fine, but the save button produces this error:
Update requires a valid UpdateCommand when passed DataRow collection with modified rows.
Here is my code:
Imports System.Data.OleDb
Public Class Form1
Dim myConString As String
Dim con As OleDbConnection = New OleDbConnection
Dim Dadapter As OleDbDataAdapter
Dim DSet As DataSet
Dim DSet2 As DataSet
Dim ConCMD As OleDb.OleDbCommand
Private Sub load_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles load_btn.Click
myConString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\Psmccsfs01\snd\PRODUCTION\Licensed\Reporting\FTO Adjustment Tools\FTO_Log_DB.accdb;"
con.ConnectionString = myConString
con.Open()
Dadapter = New OleDbDataAdapter("select * from FTO_Log", con)
DSet = New DataSet
Dadapter.Fill(DSet, "FTO_Log")
DataGridView1.DataSource = DSet.Tables("FTO_Log")
con.Close()
End Sub
Private Sub save_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles save_btn.Click
Using con = New OleDbConnection(myConString)
con.Open()
Dadapter.Update(DSet, "FTO_Log")
End Using
End Sub
End Class
dataAdpater.UpdateCommand = new SqlCommand(
"UPDATE Categories SET CategoryName = #CategoryName " +
"WHERE CategoryID = #CategoryID", connection);
notice the typo in the code above, straight from the msdn site ;p
short and simple: http://msdn.microsoft.com/en-us/library/33y2221y%28v=vs.110%29.aspx

Issue with Comobox on DataGridView

I am using VB.NET to pull some data from an SQL database into a Datagridview.
I then want the user to be able to modify the information and save it back to the database, which I have working fine.
What I need to be able to do now is to restrict the values, but way of a combobox for the field Tarrif.
I have configured a DataSource called Tarrif1 and I am using the below code.
I have a couple of issues/questions.
Firstly the dropdown shows a single value of "System.Data.DataViewManagerListItemTypeDescriptor" not the Tarrif1 values.
Secondly, I now have 2 columns on my datatable called Tarrif, the original database one and the one I have added - How can I get the ComboBox to right back to the appropriate Tarrif database field.
Here is my code:
Imports System.Data.SqlClient
Imports System.Data.Common
Public Class ViewCustomersForm
Dim ds As DataSet = New DataSet()
Dim connStr As String = "server=barry-laptop\SQLEXPRESS; database=BillingReferenceData; integrated security=yes"
Dim sql As String = "SELECT * FROM Customers"
Dim conn As SqlConnection = New SqlConnection(connStr)
Dim comm As SqlCommand = New SqlCommand(Sql, conn)
Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm)
Private Sub ViewCustomersForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'---open the connection and fill the dataset---
conn.Open()
dataadapter.Fill(ds, "Customers_table")
conn.Close()
DataGridView1.DataSource = ds
DataGridView1.DataMember = "Customers_table"
'---create a combobox column---
Dim comboBoxCol As New DataGridViewComboBoxColumn
'---set the header---
comboBoxCol.HeaderText = "Tarrifs"
'---data bind it---
comboBoxCol.DataSource = Tarrifs1
'comboBoxCol.DisplayMember = "Tarrif" // when I add these rows the new Tarrif column is not visible
'comboBoxCol.ValueMember = "Tarrif" // when I add these rows the new Tarrif column is not visible
'---add a combobox column to the DataGridView control---
DataGridView1.Columns.Add(comboBoxCol)
End Sub
Private Sub Button_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter)
sqlCmdBuilder.GetUpdateCommand()
dataadapter.Update(ds.Tables("Customers_table"))
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
End Sub
End Class
Hope that makes sense. Any help greatly appreciated.
A few things in this code:
dataadapter.Fill(ds, "Customers_table")
conn.Close()
DataGridView1.DataSource = ds
DataGridView1.DataMember = "Customers_table"
'---create a combobox column---
Dim comboBoxCol As New DataGridViewComboBoxColumn
'---set the header---
comboBoxCol.HeaderText = "Tarrifs"
'---data bind it---
comboBoxCol.DataSource = Tarrifs1
First, I'm not sure what happens whenever the code attempts to fill a DataSet that already has data in it. In my code, I never assume, so I always reinitialize it each time unless I need it:
ds = new DataSet()
Next, you are setting the DataSource for comboBoxCol as Tarrifs1, but I do not see that defined anywhere. You might want to look into that.
Finally, about the SQL: Dim sql As String = "SELECT * FROM Customers" I don't know what columns are in your Customers table. Is Tarrif an actual column?
I figured half my issue out.
I configured a second data connection to pull the Tarrif drop down from the Tarrifs table and display this as part of the customer data table.
My outstanding issues now, is that I need to write the select Tarrif value back to the Customers table.
All the other updated values save, just not sure how to write the Tarrif dropdown back to my SQL table
Here is my latest code.
Imports System.Data.SqlClient
Imports System.Data.Common
Public Class ViewCustomersForm
Dim ds As DataSet = New DataSet()
Dim connStr As String = "server=barry-laptop\SQLEXPRESS; database=BillingReferenceData; integrated security=yes"
Dim sql As String = "SELECT [Customer ID] ,[Customer Name] ,[Address] ,[City] ,[County] ,[Post Code] FROM [BillingReferenceData].[dbo].[Customers]"
Dim conn As SqlConnection = New SqlConnection(connStr)
Dim comm As SqlCommand = New SqlCommand(Sql, conn)
Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm)
Dim con As New System.Data.SqlClient.SqlConnection("server=barry-laptop\SQLEXPRESS; database=Test; integrated security=yes")
Dim strSQL As String = "SELECT * FROM Tarrifs"
Dim da As New System.Data.SqlClient.SqlDataAdapter(strSQL, con)
Private Sub ViewCustomersForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'---open the connection and fill the dataset---
conn.Open()
dataadapter.Fill(ds, "Customers_table")
conn.Close()
DataGridView1.DataSource = ds
DataGridView1.DataMember = "Customers_table"
'---create a combobox column---
Dim comboBoxCol As New DataGridViewComboBoxColumn
'---set the header---
comboBoxCol.HeaderText = "Tarrifs"
'---data bind it---
da.Fill(ds, "Tarrifs")
comboBoxCol.DataSource = ds.Tables("Tarrifs")
comboBoxCol.DisplayMember = "Tarrif"
comboBoxCol.ValueMember = "Tarrif"
'---add a combobox column to the DataGridView control---
DataGridView1.Columns.Add(comboBoxCol)
End Sub
Private Sub Button_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter)
sqlCmdBuilder.GetUpdateCommand()
dataadapter.Update(ds.Tables("Customers_table"))
dataadapter.Update(ds.Tables("Tarrifs"))
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
End Sub
End Class

How To Populate a DropDown List From a DataSet?

I am trying to populate an ASP dropdown list in vb.net with the results from a stored procedure returned in a data set. I was wondering if anyone knew the vb.net code to populate the dropdown list?
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim connString As String = "Server=MYCOMPUTER\SQLEXPRESS;Database=scales;Trusted_Connection=True"
Dim myConn As New SqlConnection(connString)
myConn.Open()
Dim da As New SqlDataAdapter("select scaleName from scales", myConn)
Dim dt As New DataTable
da.Fill(dt)
ComboBox1.DisplayMember = "scaleName"
ComboBox1.DataSource = dt
myConn.Close()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
IF Not IsPostback then
PopulateDropdown()
End IF
End Sub
Private Sub PopulateDropDown()
Dim connString As String = "Server=MYCOMPUTER\SQLEXPRESS;Database=scales;Trusted_Connection=True"
Dim myConn As New SqlConnection(connString)
myConn.Open()
Dim da As New SqlDataAdapter("select ScaleId, scaleName from scales", myConn)
Dim dt As New DataTable
da.Fill(dt)
Me.ComboBox1.DataTextField = "scaleName "
Me.ComboBox1.DataValueField = "ScaleId"
Me.ComboBox1.DataSource = dt
Me.ComboBox1.DataSourceID = String.Empty
Me.ComboBox1.DataBind()
myConn.Close()
End Sub
In order to show the data in the DropDownList control, you can use the following Code. To use the results of a Stored Procedure, you need to create the SELECT command:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Dim dt As New DataTable
Dim connString As String = "Server=MYCOMPUTER\SQLEXPRESS;Database=scales;Trusted_Connection=True"
Using myConn As New SqlConnection(connString)
myConn.Open()
Using cmd = myConn.CreateCommand()
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "dbo.uspMyStoredProc"
cmd.Parameters.AddWithValue("#MyInputParam", 123)
Using da As New SqlDataAdapter(cmd)
da.Fill(dt)
End Using
End Using
End Using
ComboBox1.DisplayMember = "scaleName"
ComboBox1.DataSource = dt
ComboBox1.DataBind()
End If
' ...
End Sub
I've adjusted the following things:
Usually you only need to bind the data on the initial request. Therefore, the if statement at the beginning checks the IsPostBack property.
In order to close and dispose the connection and the data datapter reliably, I've added some using statements.
In order to access the stored procedure, I've created a SqlCommand and set the CommandType to StoredProcedure. The CommandText is set to the name of the Stored Procedure. In the sample, I've also added a parameter named MyInputParam that is sent to the Stored Procedure.

VB.NET 2008 DataGridView not Updating Visual Foxpro Database

I'm using VB.NET 2008 with a DataGridView and I'm interfacing to a Visual Foxpro 6 database using the vfpoledb.1 driver. When I change a value in the description field, it changes in the DataGridView but the database never gets updated. Do I need to use code to force the changes to take place?
Here's the code I'm using:
Imports System.Data.OleDb
Public Class Form1
Dim sConString As String = "Provider=vfpoledb.1;Data Source=C:\MyDatabase.dbc;Mode=3;"
Dim con As OleDbConnection = New OleDbConnection(sConString)
Private Function FetchData()
con.Open()
Dim ds As DataSet = New DataSet()
Dim sSQL As String
sSQL = "SELECT item_cd, item_desc FROM invent;"
Dim cmd As OleDbCommand = New OleDbCommand(sSQL, con)
Dim daInv As OleDbDataAdapter = New OleDbDataAdapter(cmd)
Dim iRecCount As Integer
iRecCount = daInv.Fill(ds, "invent")
Me.DataGridView1.DataSource = ds.Tables("invent").DefaultView
End Function
Private Sub btnFetchData_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnFetchData.Click
Call FetchData()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
con.Close()
con = Nothing
End Sub
End Class
Did this code will update the Table and push the changes back to Database? I don't think so. I tried the same code with SQL Server 2005, and it is not working(I don't have a FoxPro db). So I modified the code and now it is working fine.
Imports System.Data.OleDb
Public Class Form1
Dim sConString As String = "Provider=vfpoledb.1;Data Source=C:\MyDatabase.dbc;Mode=3;"
Dim con As OleDbConnection = New OleDbConnection(sConString)
Dim daInv As OleDbDataAdapter
Dim ds As DataSet = New DataSet()
Private Sub FetchData()
con.Open()
Dim sSQL As String
sSQL = "SELECT item_cd, item_desc FROM invent;"
Dim cmd As OleDbCommand = New OleDbCommand(sSQL, con)
daInv = New OleDbDataAdapter(cmd)
Dim builder As New OleDbCommandBuilder(daInv)
Dim iRecCount As Integer
iRecCount = daInv.Fill(ds, "invent")
Me.DataGridView1.DataSource = ds.Tables("invent").DefaultView
End Sub
Private Sub btnFetchData_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnFetchData.Click
Call FetchData()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
daInv.Update(ds.Tables("invent"))
con.Close()
con = Nothing
End Sub
End Class
Hope it works :)
I found the underyling problem and resolved it. The VFP table I'm accessing does not have a primary key defined. It does have indexes but they are simply marked as "Regular" indexes (using VFP terminology).
I was able to use a VFP tool call vRunFox (Visual Run Fox) from Ed Leafe's website to modify the table structure. I had to use some VFP commands to bring up the Table Designer window.
I also had to add some code to my FormClosing event. Here's what my FormClosing event looks like now:
Dim myBuilder As OleDbCommandBuilder = New OleDbCommandBuilder(daInv)
myBuilder.GetUpdateCommand()
daInv.UpdateCommand = myBuilder.GetUpdateCommand
daInv.Update(ds.Tables("invent"))
con.Close()
con = Nothing