I have a parent-child relation setup between two tables. The parent table is setup with an auto increment value for its primary key. This is working fine and the new row in the parent DataTable is refreshed with the actual value of the key that was just inserted when I call Update on the TableAdaptor.
The problem is that the rows from the child table are not being inserted into the DB. For debug purposes, I added changesBefore and changesAfter to the code sample to see what changed rows exist in the child table. When I step through the code with a debugger, changesBefore constains the new child rows. changesAfter is Nothing. Its almost as if calling Update against the header table is triggering AcceptChanges on the child table.
I am familiar with insert/updating with DataTables and TableAdapters but this is my first attempt at using an autoincrement on a parent table. What am I missing here?
Dim changesBefore = _ds.ResponseDetails.GetChanges
headersTa.Update(_ds.ResponseHeaders)
Dim changesAfter = _ds.ResponseDetails.GetChanges
detailsTa.Update(_ds.ResponseDetails)
After doing the header update, you need to update the linking field in the detail record with the auto generated id from the header record. This does not happen automatically for you.
This is working now. Turns out there is an AcceptRejectRule property for each relation in a data set. I had the rule set to Cascade so it was basically cascading AcceptChanges down to the child table when Update was called against the parent. Changing the rule to None resolved my issue.
http://msdn.microsoft.com/en-us/library/system.data.acceptrejectrule(v=vs.80).aspx
Related
I have two tables in MSSQL which are related tbl1.PK tbl2.PK, tbl2FK(_tbl1PK)
I have created a dataset in Visual Studio and they show up with the relation
when I drop the tables as datagrids onto a form I get the parentDG and childDG.
VS adds in the binding navigator which adds the save procedure
tbl1.bindingsource.endedit
tableadaptermanager.updateall
When I add data to the parentDG and press save the data gets saved to the DB.
When I add a new parent and then add a new child details and press save I get
System.Data.SqlClient.SqlException: 'The INSERT statement conflicted with the FOREIGN KEY constraint "FK_tblChild_tblParent". The conflict occurred in database "xxxxx", table "dbo.tblParent", column 'PK'.
I have tried updating the parentTableadapter and then ds.acceptchanges but I can not get the new child row to update.
I understand why but my questions are:
isn't the VS IDE supposed to handle this?
if isn't for me so I presume I need to get the new tbl1PK (scope_identity).
I can see in the dataset code the insert command:
Me._adapter.InsertCommand.CommandText = "INSERT INTO [] FROM tbl1 WHERE (PK= SCOPE_IDENTITY())"
BUT I cannot for the life of me see how to get this value.
I have a lot of tables with a lot of columns which is why I want/need to use the power of the IDE to populate and bind my controls and so I really do not want to go down the route of manually creating my datasets.
I have searched and searched on this and can't find anything that speaks to how you do this using VS auto generated code.
thanks
John
I just tested and the addition of the query in the InsertCommand happened automatically so you must not have done something properly. Here's EXACTLY what I did:
Created a new database named Test on my local default SQL Server instance via SSMS.
Added a table named Parent with columns ParentId (int, PK, identity) and ParentName (varchar).
Added a table named Child with columns ChildId (int, PK, identity), ParentId (int) and ChildName (varchar).
Created a foreign key in the Child table to the ParentId column from the ParentId column in the Parent table, setting the Update Rule to Cascade.
Created a new VB Windows Forms application project.
Added a new Data Source via the Data Sources window for the Test database.
Opened the TestDataSet from the Solution Explorer in the DataSet designer.
Selected the DataRelation between the two DataTables.
In the Properties window, clicked Edit Relation.
Checked 'Both Relation and Foreign Key Constraint', when Update Rule changed automatically to Cascade.
At this point, but even after step 7, I was able to select the ParentTableAdapter in the designer, expand the InsertCommand and view the CommandText to see this:
INSERT INTO [dbo].[Parent] ([ParentName]) VALUES (#ParentName);
SELECT ParentId, ParentName FROM Parent WHERE (ParentId = SCOPE_IDENTITY())
If you don't see that, you can set it yourself. What happens now is that, when the InsertCommand is executed to insert a new record, that query immediately retrieves the data from that record back into the DataRow in your DataSet. That will update the ParentId column with the newly generated value and the Update Rule will cause that new value to cascade to any related DataRows in the Child DataTable, so you can just go ahead and insert them without worry.
Let's say I have a customer parent table and an orders child table. I set createconstraints to true for the datarelation, and I also add foreignkeyconstraints for delete and update to cascade. All works as expected. Now let's say the number of customer records gets so large I have to load only subsets of the customer records into the dataset. However, the number of order records is still manageable, so I continue to load them all in. When adding the datarelation if an order exists and I didn't happen to load in the parent customer record I get an error. So I try to set the createconstraints of the datarelation to false. Now the datarelation will load, but I get an error when trying to add a foreignkeyconstraint.
Since I will work only with the customer records that are currently loaded in the dataset, and essentially ignore any order records whose parent customer record is not present, how can I do this and still have the benefit of the foreignkeyconstraint cascading my deletes and updates? I guess I could only load the order records whose parent is present, but I was looking for an easier way. Thanks for any advice.
Parent (licenseID, countChilds)
Child (hostID, licenseID)
Trying to write an after insert/update/delete trigger that fires when adding a record to the child table. It needs to count child records linked to the parent and then insert this value into the parent.
But I keep getting the SQL statement is not valid.
So far I have this:
I am using MS Access 2010.
I am fairly sure you can get away with DCount, for example, this works for me:
But I would still recommend not doing this and just getting your counts from a query.
This seems to work, at least for After Insert:
The After Update Data Macro would be a bit more involved because it might have to update two [License] records (one for [Host].[licenseID] and another for [Old].[licenseID]), or perhaps none (if [Host].[licenseID] did not change).
I'm fairly new to phpMyAdmin, and I've come across a problem...
I have two tables in my database, Parent and Child. Both have an ID and username field, and I've set up the foreign key in working order (e.g. if I change the Parent.id, the Child.id get changed aswell.
However, I wish the Child table would automatically create a new record for each new entry made in the parent. So if I create a new Parent.id, Child should display the newly created Parent.id.
Example when I insert into Parent a new username, it'll get ID of 1 and username 'Daniel'.
I want child to have these values aswell in Child.id and Child.username respectively, so Child gets filled with 1, 'Daniel' aswell.
As for now, Child remains empty with every record I insert into Parent.
Is there a 1:1 relationship between parent and child? (Typically we use the terms 'parent' and 'child' to refer to two sides of a 1:M relationship, so that is a little confusing.)
Have you considered a trigger? The trigger would update the child the way you want, each time you do something to the parent. Here is the description of how to add a trigger to an insert command in MySQL.
I've manually created some data adapters – using the auto-generated ones is not viable due to version incompatibilities, for a dataset made of a number of tables with the usual mixture of PK, FK constraints. Most of its working pretty smoothly so far, but after modifying the adapters to use DB sequences for the PKs (instead of the temporary one assigned to the rows in the dataset) when updating the DB with new ‘added’ rows, I’ve been hitting problems.
I added the sequences into the insert statements and changed PK parameter to output parameters, so that it would update the dataset row and thus update all the child rows as well (with the UPDATE CASCADE rule). The problem is that the child rows, that, before the update had a row state of added, are changed to a state of modified (I don’t agree this should even be happening, surely an added row should stay as added even if it’s modified!). Thus when we get round to updating the child table with the child rows, it fails as its expecting rows with the added state.
What’s the cleanest way I could get around this problem? Potential solutions I can think of:
Turning off UPDATE CASCADE and updating each child row manually after, updating the parents PK and changing each row back to added, after modifying it.
Creating a copy of the all the added rows in all tables of the dataset before starting updates and then updating the main copy after each tables updates marking all the correct rows back to added.
Any better ideas?