PostgreSQL delete from parent table only - sql

I have a table structure with partitioned tables, where a few child tables inherit from a common parent. How so I DELETE only from the parent table?
Long story short, I ended up with some data in the parent table, and this should've never happened but now I have to clean up the mess.

You can specify that only parent table matters, simply by using keyword 'ONLY':
DELETE FROM ONLY parent_table_name;
See: http://www.postgresql.org/docs/current/static/sql-delete.html

Related

Delete records from relational database with no cascade involved

I need to delete records from relational database, where I attempt to start from the lowest children in the database.
I'm not very strong on how to approach the task. I don't want to do CASCADE delete, I actually want to do the opposite of CASCADE.
Is is correct that I have to find the entity that does not have child and start deleting the records there? and what if an entity has more that one foreign key, how do I decide on which parent table should I start to delete from?
You have to delete the child records first. If you try to delete a record that is referenced with a foreign key, you will get an error which should indicate which key has a conflict. You can then see which child table is impacted and delete the records that are referencing the foreign key, then try again.
You simply work your way up the chain. If more than one child record references a parent record, you simply delete all the child records first. If more than one parent record is referenced by a child record, it doesn't matter which parent is deleted first (or if they are deleted at all).
You don't give what database and what tools you have at hand.
You could manually diagram the database based on foreign keys or you could use a tool, such as visual studios to diagram your database.
As long as the multiple foreign relationships don't depend on one another it shouldn't matter where you start.

Parent & Child FK'ing to same table

What is best practise when a parent & child table both FK to the same table?
Parent > Child(ren)
CommonAttributes: Sex, Age, Height, Weight
Is it better to directly reference the common table:
CommonAttributes > Parent(s) > Child(ren)
&
CommonAttributes > Child(ren)
Or use a reference table:
RefTable: CommonAttributes_Id, Parent_Id(null), Child_Id(null)
I think the first method works OK (with regards to EF) but it is a bit of a circular reference. Is it better to use a reference table to define the constraints?
There are several approaches to this and the one you need depends on your business needs.
First, can a child record have more than one parent? For instance you might be modelling an organizational structure where an employee can have two supervisors. If this is true, then you have a one to many relationship and need a separate table for this model to work.
If you are guaranteed to have only one parent per child (but each parent might have a parent (building a hierarchy), then you can model this is one table. The table structure would include the Primary key, say UserID and then a nullable column for the parent such as ParentUserID. Then you can create the foreign key to the field in the same table.
ALTER TABLE dbo.Mytable ADD CONSTRAINT FK_Mytable _UserPArent FOREIGN KEY (ParentUserD) REFERENCESdbo.Mytable (UserID)
If you want to build a hierarchy in a query, you then use a recursive CTE to get it. See example here:
https://msdn.microsoft.com/en-us/library/ms186243.aspx
Another time you might want to build a separate table for the child parent relationship is if only a small portion of teh records in the main table would have parent child relationships. For instance suppose you had a people table that stored, sales reps and customers. Only sales reps would have a parent child relationship. So you would want a separate SalesRepHierarchy table to store it which woudl make querying more straightforward.
While in general you woudl want to create hierarchies in a recursive CTE, there are special cases when it might be faster to pre calculate the hierarchies. This is true if the hierarchy is frequently queried, the CTE performance is slow and you have control over how the hierarchy is built (preferably through an import of data only) and if it changes fairly rarely (you would not want to be rebuilding the hierarchy every minute, but a once a day import can be accommodated. This can greatly speed up and simply querying for the whole hierarchy, but is not recommended if the parent child relationships are created and changed constantly through the application.

What is the steps for splitting childs table in postgresql?

I have a Postgresql database, where many tables inherit from a common root table.
What are the SQL commands to use for removing the root table, but keeping data and final schema for each table?
Thanks.
A parent table cannot be dropped while any of its children remain. Neither can columns or check constraints of child tables be dropped or altered if they are inherited from any parent tables. If you wish to remove a table and all of its descendants, one easy way is to drop the parent table with the CASCADE option.
Source

Why am I getting "multiple cascade paths" with this table relationship?

I have the following table relationship in my database:
Parent
/ \
Child1 Child2
\ /
GrandChild
I am trying to create the FK relationships so that the deletion of the Parent table cascades to both child and the grandchild table. For any one particular granchild, it will either be parented to one or the other child tables, but never both at the same time.
When I'm trying to add ON DELETE CASCADE to the FK relationships, everything is fine adding them to one "side" of the two children (Parent-Child1-GrandChild is fine for Cascade Delete). However, as soon as I add the Cascade Delete on the Child2 "side" of the relationship SQL tells me that the FK would cause multiple cascade paths. I was under the impression that multiple cascade paths only apply when more than one FK indicates the SAME table. Why would I be getting the multiple cascade paths error in this case?
PS The table relationships at this point would be very difficult to change so simply telling me to change my table structure is not going to be helpful, thanks.
The message means that if you delete a Parent record, there are two paths that lead to all deletable GrandChild records.
Fix: Remove the ON DELETE CASCADE options in the FKs, and create INSTEAD OF DELETE triggers for the ChildX tables, deleting all grandchild records, and then the childX records themselves.

Inheritance in database?

Is there any way to use inheritance in database (Specifically in SQL Server 2005)?
Suppose I have few field like CreatedOn, CreatedBy which I want to add on all of my entities. I looking for an alternative way instead of adding these fields to every table.
There is no such thing as inheritance between tables in SQL Server 2005, and as noted by the others, you can get as far as getting help adding the necessary columns to the tables when you create them, but it won't be inheritance as you know it.
Think of it more like a template for your source code files.
As GateKiller mentions, you can create a table containing the shared data and reference it with a foreign key, but you'll either have to have audit hooks, triggers, or do the update manually.
Bottom line: Manual work.
PostgreSQL has this feature. Just add this to the end of your table definition:
INHERITS FROM (tablename[, othertable...])
The child table will have all the columns of its parent, and changes to the parent table will change the child. Also, everything in the child table will come up in queries to the parent table (by default). Unfortunately indices don't cross the parent/child border, which also means you can't make sure that certain columns are unique across both the parent and child.
As far as I know, it's not a feature used very often.
You could create a template in the template pane in Management Studio. And then use that template every time you want to create a new table.
Failing that, you could store the CreatedOn and CreatedBy fields in an Audit trail table referencing the original table and id.
Failing that, do it manually.
You could use a data modeling tool such as ER/Studio or ERWin. Both tools have domain columns where you can define a column template that you can apply to any table. When the domain changes so do the associated columns. ER/Studio also has trigger templates that you can build and apply to any table. This is how we update our LastUpdatedBy and LastUpdatedDate columns without having to build and maintain hundreds of trigger scripts.
If you do create an audit table you would have one row for every row in every table that uses the audit table. That could get messy. In my opinion, you're better off putting the audit columns in every table. You also may want to put a timestamp column in all of your tables. You never know when concurrency becomes a problem. Our DB audit columns that we put in every table are: CreatedDt, LastUpdatedBy, LastUpdatedDt and Timestamp.
Hope this helps.
We have a SProc that adds audit columns to a given table, and (optionally) creates a history table and associated triggers to track changes to a value. Unfortunately, company policy means I can't share, but it really isn't difficult to achieve.
If you are using GUIDs you could create a CreateHistory table with columns GUID, CreatedOn, CreatedBy. For populating the table you would still have to create a trigger for every table or handle it in the application logic.
You do NOT want to use inheritance to do this! When table B, C and D inherits from table A, that means that querying table A will give you records from B, C and D. Now consider...
DELETE FROM a;
Instead of inheritance, use LIKE instead...
CREATE TABLE blah (
blah_id serial PRIMARY KEY
, something text NOT NULL
, LIKE template_table INCLUDING DEFALUTS
);
Ramesh - I would implement this using supertype and subtype relationships in my E-R model. There are a few different physical options you have of implementing the relationships as well.
in O-R mapping, inheritance maps to a parent table where the parent and child tables use the same identifier
for example
create table Object (
Id int NOT NULL --primary key, auto-increment
Name varchar(32)
)
create table SubObject (
Id int NOT NULL --primary key and also foreign key to Object
Description varchar(32)
)
SubObject has a foreign-key relationship to Object. when you create a SubObject row, you must first create an Object row and use the Id in both rows