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.
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.
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 have a Dimensional table structure which resembles the following:
Ideally the hierarchial representation should be
CodeClassDesc --> CodeDesc
So A would be a Parent to A and B; B would be a Parent to A, B and C in my Analysis Server Cube. The problem is that because CodeClassDesc has multiple entries in the table it produces multiple duplicate Parents in my Cube with a single corresponding Child Element per Parent which is not what I'd consider a true Hierarchy. Or at least not what I am looking for the expected results.
I believe this is possible in SSAS without having to manipulate the data within the table via a VIEW but I don't know what I'm missing.
I've tried defining the CodeClassDesc and CodeDesc fields as a composite key but that doesn't work, yet I am almost certain there is a way to do this.
After attempting every conceivable permutation of methods to acquire resolution for this, I concluded that normalization of the required attribute was the only way to resolve the issue of having multiple entries of the Parent for every corresponding Child element.
So I created a VIEW of the table using a DISTINCT SELECT of only the CodeClass and CodeClassDesc fields in my DSV (DataSource View) in the Cube. Then I set the CodeClass field as a logical Primary Key and created a relationship between it and the CodeClass field of the main table.
I then used the CodeClassDesc field of the VIEW to create the top-level parent in my Dimension, which gave me only 1 distinct record for each value; and added the CodeDesc fields from the Table to create the Child Relationships. Works like a charm so I guess the answer would have to be that you cannot create a Parent Hierarchy consisting of a single Value per Parent if the source has multiple records.
In the dimension structure, you should change the property KeyColumn of the attribute "CodeClassDesc" to a composite key containing both "CodeClassDesc" and "CodeDesc" then change the NameColumn property to show itself
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
We have a two tables with a one-to-many relationship. We would like to enforce a constraint that at least one child record exist for a given parent record.
Is this possible?
If not, would you change the schema a bit more complex to support such a constraint? If so how would you do it?
Edit: I'm using SQL Server 2005
Such a constraint isn't possible from a schema perspective, because you run into a "chicken or the egg" type of scenario. Under this sort of scenario, when I insert into the parent table I have to have a row in the child table, but I can't have a row in the child table until there's a row in the parent table.
This is something better enforced client-side.
It's possible if your back-end supports deferrable constraints, as does PostgreSQL.
How about a simple non nullable column?
Create Table ParentTable
(
ParentID
ChildID not null,
Primary Key (ParentID),
Foreign Key (ChildID ) references Childtable (ChildID));
)
If your business logic allows and you have default values you can query from the database for each new parent record, you can then use a before insert trigger on the parent table to populate the non nullable child column.
CREATE or REPLACE TRIGGER trigger_name
BEFORE INSERT
ON ParentTable
FOR EACH ROW
BEGIN
-- ( insert new row into ChildTable )
-- update childID column in ParentTable
END;
This isn't really something 'better enforced on the client side' so much as it is something that is impractical to enforce within certain database implementations. Realistically the job DOES belong in the database and at least one of the workarounds below should work.
Ultimately what you want is to constrain the parent to a child. This guarantees that a child exists. Unfortunately this causes a chicken-egg problem because the children must point to the same parent causing a constraint conflict.
Getting around the problem without visible side-effects in the rest of your system requires one of two abilities - neither of which is found in SQL Server.
1) Deferred constraint validation - This causes constraints to be validated at the end the transaction. Normally they happen at the end of a statement. This is the root of the chicken-egg problem since it prevents you from inserting either the first child or the parent row for lack of the other and this resolves it.
2) You can use a CTE to insert the first child where the CTE hangs off of the statement that inserts the parent (or vise versa). This inserts both rows in the same statement causing an effect similar to deferred constraint validation.
3) Without either you have no choice but to allow nulls in one of the references so you can insert that row without the dependency check. Then you must go back and update the null with the reference to the second row. If you use this technique you need to be careful to make the rest of the system refer to the parent table thru a view that hides all rows with null in the child reference column.
In any case your deletes of children are just as complicated because you cannot delete the child that proves at least one exists unless you update the parent first to point to a child that won't be deleted.
When you are about to delete the last child either you must throw an error or delete the parent at the same time. The error will occur automatically if you don't set the parent pointer to null first (or defer validation). If you do defer (or set the child pointer to null) your delete of the child will be possible and the parent can then be deleted as well.
I literally researched this for years and I watch every version of SQL Server for relief from this problem since it's so common.
PLEASE As soon as anyone has a practical solution please post!
P.S. You need to either use a compound key when referring to your proof-of-child row from the parent or a trigger to insure that the child providing proof actually considers that row to be its parent.
P.P.S Although it's true that null should never be visible to the rest of your system if you do both inserts and the update in the same transaction this relies on behavior that could fail. The point of the constraint is to insure that a logic failure won't leave your database in an invalid state. By protecting the table with a view that hides nulls any illegal row will not be visible. Clearly your insert logic must account for the possibility that such a row can exist but it needs inside knowledge anyway and nothing else needs to know.
I am encountering this issue, and have a solution implemented in Oracle rel.11.2.4.
To ensure that every child has a parent, I applied a typical foreign-key constraint from the FK of the child to the PK of the parent. -- no wizardry here
To ensure that every parent has at least one child, I did as follows:
Create a function which accepts a parent PK, and returns a COUNT of children for that PK. -- I ensure that NO_DATA_FOUND exceptions return 0.
Create a virtual column CHILD_COUNT on the parent table and calculate it to the function result.
Create a deferrable CHECK constraint on the CHILD_COUNT virtual column with the criteria of CHILD_COUNT > 0
It works as follows:
If a parent row is inserted and no children exist yet. then if that row is committed, the CHILD_COUNT > 0 CHECK constraint fails and the transaction rolls back.
If a parent row is inserted and a corresponding child row is inserted in the same transaction; then all integrity constraints are satisfied when a COMMIT is issued.
If a child row is inserted corresponding to an existing parent row, then the CHILD_COUNT virtual column is recalculated on COMMIT and no integrity violation occurs.
Any deletes of parent rows must cascade to the children otherwise orphaned child rows will violate the FOREIGN KEY constraint when the delete transaction is committed. (as usual)
Any deletes of child rows must leave at least one child for each parent otherwise the CHILD_COUNT check constraint will violate when the transaction commits.
NOTE: that I would not need a virtual column if Oracle would allow user-function-based CHECK constraints at rel.11.2.4.