I am hitting an MS Access db with VB2005 and I am creating a table object like this
Dim sSQL As String = "SELECT * FROM tblCars WHERE WeekOf=#6/1/2011#"
Dim da As New OleDb.OleDbDataAdapter(sSQL, conn)
Dim ds As New DataSet
da.Fill(ds, "CarData")
Dim cb As New OleDb.OleDbCommandBuilder(da)
The table should have no rows since the data is brand new. I read a data text file with new data and pump this data into the table and add new rows like so:
'create a new empty row
Dim dsNewRow As DataRow = ds.Tables("CarData").NewRow()
'update the new row with fresh data
dsNewRow.Item("DriveDate") = dd
dsNewRow.Item("DCode") = dc
dsNewRow.Item("CarNum") = carID
'about 15 more fields
'add the filled row to the DataSet table
ds.Tables("CarData").Rows.Add(dsNewRow)
'end loop
'update the database with the new rows
da.Update(ds, "CarData")
The table in the db has no primary keys but all this works and i get all my new data inserted into the Data table tblCars.
Now it so happens that I must also account for cars with no data. For that my plan was to get a list of cars from the control table and merge it with the Data table.
Dim sSQL As String = "SELECT CarId FROM tblControlCars WHERE ActiveCar=True;"
Dim daAct As New OleDb.OleDbDataAdapter(sSQL, conn)
Dim ds As New DataSet
daTail.Fill(ds, "ActCars")
Dim cbAct As New OleDb.OleDbCommandBuilder(daAct)
I then create my primary keys for the tables and then merge them.
ds.Tables("CarData").Merge(ds.Tables("ActCars"))
This will give me a table with all the new data for cars that do have data and also a place holder for those cars that are active but did not get any data. However, when I try to do an update back to the db I get an error
System.InvalidOperationException: Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not return any key column information.
I'm not sure I understand why the Merged data is not able to be pushed to the database.
I've had the same problem before just add a primary key in your database table , the command builder needs a unique identification field to generate a proper command .
You can simply create a field called "id" and make auto-number then you don't have to update it manually and make it a primary key that's it
Related
I am trying to update my SQL database with the code provided, I am basically trying to take a select statement to bring back just the INTGenderID based on a combo box and make it equal to a string then convert that to an integer when I do my update back into my database. If you need more info let me know. The main table is TGolfers and the parent table is TGenders.
I think I understand the question. Let's assume that you have a database table named Thing and that has columns ThingId and Name. You would generally query the database to populate a DataTable and then bind that to your ComboBox, e.g.
Dim table As New DataTable
Using connection As New OleDbConnection(connectionString),
command As New OleDbCommand("SELECT ThingId, Name FROM Thing", connection)
connection.Open()
Using reader = command.ExecuteReader()
table.Load(reader)
End Using
End Using
With thingComboBox
.DisplayMember = "Name"
.ValueMember = "ThingId"
.DataSource = table
End With
The user will now see a list of Name values in the ComboBox and, when they select one, you can get the corresponding ThingId from the SelectedValue property, e.g.
Dim thingId = CInt(thingComboBox.SelectedValue)
I am converting an old 2010 Access data base to Access 2016, the database being originally built in Access 2000. My customer table used an autonumber field to generate a CustomerId number.
I used this field to connect to my repairs table which currently has 13,000 records. I have not been able to find away to maintain this field in new database, so I thought if I can export the table to an Excel file than add numbers in sequence of missing ID numbers along with data to fill name and address fields for temp import to new database, after import I can delete these fields.
I don't know if there are other ways to maintain this id. I imported customer table with Old ID field name, but access won't allow me to use this field to create relationships to new repairs table.
The ID numbers go from 1 to 8,437 yet there are only 7,884 records in the spreadsheet.
The best way to resequence the IDs is to take advantage of "Cascade Update Related Fields".
What you will have to do is
Delete all the relationships to your table
Change the ID field to Number - Long Integer
Add the relationships back, inforcing cascading updates
Shift all the indices to a number larger than the current max ID
Renumber than starting at 1
Delete all the relationships
Delete the ID field
Save the table
Add the ID field back as auto-increment - primary key
Add the relationships back
ReImcrementCustomerIDs:Sub
Option Compare Database
Option Explicit
Public Sub ReImcrementCustomerIDs(ByVal FirstIndex As Long)
Dim rs As DAO.Recordset
Dim db As Database
Dim SQL As String
Dim ID As Long
Set db = CurrentDb
SQL = "SELECT CustomerID FROM Customers ORDER BY CustomerID;"
Set rs = db.OpenRecordset(SQL, dbOpenDynaset)
Do While Not rs.EOF
rs.Edit
rs("CustomerID") = FirstIndex
FirstIndex = FirstIndex + 1
rs.Update
rs.MoveNext
Loop
End Sub
Usage
ReImcrementCustomerIDs 50000
ReImcrementCustomerIDs 1
I am using Data Source and Data Table to retrieve Data for Report viewer. Currently I have a requirement to add new column to Data table. Therefore I added new column to the data table. But SqlDataProvider.Fill Function is not filling data for newly added column. I want to know how can I modify the data set when Data or store procedure got changed. enter image description here
string queryString =
"SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
For more detail check
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/populating-a-dataset-from-a-dataadapter
I tried many times to create a master view of the table along with its details and visualize that in a Gridcontrol (from Devexpress)
here is the code
*I do not want to rely on the automatic generation of codes by Devexpress designer!
' DEFINE A DATASET TO HOLD TABLES INSIDE
Dim dataset As New DataSet
'IF THE CONNECTION IS POSSIBLE THEN PROCCEED
If sqlcontrol.HasConnection Then
' SELECT ALL RECORDS FROM THE SUPPLIERS TABLE (MASTER TABLE)
sqlcontrol.ExecQuery("SELECT * FROM [Suppliers]")
' FILL IN THAT TABLE INTO THE DATASET
dataset.Tables.Add(sqlcontrol.SQLdatatable)
' SELECT ALL RECORDS FROM THE SUPPLIERSPERSONNEL (DETAIL TABLE)
sqlcontrol.ExecQuery("SELECT * FROM [SuppliersPersonnel]")
'FILL IN THAT TABLE INTO THE DATASET
dataset.Tables.Add(sqlcontrol.SQLdatatable)
'INVOKE THE BINDING SOURCE INTO THE GRIDVIEW
Me.GridControl1.DataSource = dataset
End If
hopefully it worked but not like a master-detail view.
it showed every table on its own.
The Dataset itself indeed contains the tables, yet the relations between tables are missing and did not retrieved from the SQL tables, hence why this relationship needs to be added inside the Dataset in VB.
so the code is like the following:
' DEFINE A DATASET TO HOLD TABLES INSIDE
Dim dataset As New DataSet
'IF THE CONNECTION IS POSSIBLE THEN PROCCEED
If sqlcontrol.HasConnection Then
' SELECT ALL RECORDS FROM THE SUPPLIERS TABLE (MASTER TABLE)
sqlcontrol.ExecQuery("SELECT * FROM [Suppliers]")
' FILL IN THAT TABLE INTO THE DATASET
dataset.Tables.Add(sqlcontrol.SQLdatatable)
' SELECT ALL RECORDS FROM THE SUPPLIERSPERSONNEL (DETAIL TABLE)
sqlcontrol.ExecQuery("SELECT * FROM [SuppliersPersonnel]")
'FILL IN THAT TABLE INTO THE DATASET
dataset.Tables.Add(sqlcontrol.SQLdatatable)
'Add the relation to the dataset
dataset.relations.add("CustomRelation",
dataset.tables(0).columns(0),
dataset.tables(1).columns(1), false)
'INVOKE THE BINDING SOURCE INTO THE GRIDVIEW
Me.GridControl1.DataSource = dataset
End If
By such way, the Gridcontrol works as expected !
I'm trying to progress my programming abilities by coding in Visual Basic forms. I've created a database and linked that to a VB form, I'm now coding a way to write into the database instead of reading.
I'm filling an array which is in-turn put into the dataset row by row however when attempting to 'update' the table adapter I get the following error:
Update requires a valid UpdateCommand when passed DataRow collection with modified rows.
I believe this has something to do with primary keys, the table that my adapter is updating does NOT have a primary key as it's involved in a relationship with another table, containing a primary key. How can I update my table adapter without getting this error? Thanks.
The error message you've mentioned has nothing to do with primary keys on the table you are attempting to update, instead it's complaining because you haven't given your adapter a valid command which it can use to update the underlying table.
You'd hit the same error if you attempted to insert or delete new rows without specifying an insert or delete command on your adapter.
To solve the problem, initialise your UpdateCommand property to something meaningful, for example:
'Open connection
Using Conn as new OleDbConnection("connection string")
'This is the command that will update your table in the database
Using UpdateCmd = Conn.CreateCommand()
UpdateCmd.CommandText = "update yourtable set col1 = ?, col2 = ?"
'Create a parameter to pass in the value of the "col1" column on "yourtable"
Dim ColOneParam = UpdateCmd.Parameters.Add("#Col1", OleDbType.Integer)
ColOneParam.SourceColumn = "Name of column in DataTable which corresponds to col1"
'Create a parameter to pass in the value of the "col2" column on "yourtable"
Dim ColTwoParam = UpdateCmd.Parameters.Add("#Col2", OleDbType.Integer)
ColTwoParam.SourceColumn = "Name of column in DataTable which corresponds to col2"
'Data adapter which will perform the specified update command for each
'newly inserted row
Using Adapter As New OleDbDataAdapter
'Set the update command on the adapter, if you omit this line you'll
'encounter the original error you mentioned
Adapter.UpdateCommand = UpdateCmd
'This is the data table containing the rows you wish to update
Dim NewRows As New DataTable("SomeTable")
'For each modified row in NewRows, update it in the database
Adapter.Update(NewRows)
End Using
End Using
End Using
The above code assumes a table in the database called yourtable with two columns col1 and col2 which are numeric.
The Using blocks simply ensure that the database objects are properly disposed off so you don't end up leaking resources.