What is the best way to delete a table referenced by a foreign keys?
Is the intended goal to orphan those records and never use the foreign key again? If so the method mentioned before about disabling the key is fine, otherwise you may want to instead delete the records referencing the table you want to delete first (or update the to point to a more appropriate record, or NULL if that makes sense in this case). I seem to be coming at this from a different direction than others, are you sure the foreign key is pointless, and if so why not just remove it? At some point someone wanted to constraint this behavior, before just disabling constraints I make sure I understand their purpose and have a good justification for bypassing those safeguards.
Remove the foreign key constraint and then delete the table once no-one is forced to recognize it. If the column in the second table (the one not being deleted) is not used elsewhere, then you should probably delete the whole column after removing the constraint.
You need to remove the constraint before you're allowed to delete the table referenced by it. SQL Server uses the following syntax:
ALTER TABLE <table_name> DROP FOREIGN KEY <foreignkey_name>
Keep in mind that the constraint exists on the table that references the one you want to delete so that's the table you should be altering.
Do NOT delete a table with foreign key constraints without considering the impact on the foreign key tables. Let me explain the impact of simply deleting the foreign key and then the table with an example.
Consider two tables - parts and orderdetails. There is a foreign key constraint that says a part must exist before it can be put into the orderdetails table. What is stored in the orderdetail table is the id for the part from the parts table, not the part name or description. Suppose you drop the foreign key and then drop the parts table. Now all the data in the orderdetail table is totally useless because you have no way of knowing what the part ordered was. This would include orders not yet shipped and orders that the customer might call and ask questions about. Further you now have no way to recreate that data except by restoring a backup (hope you have one).
Further suppose you want to drop the table and recreate it to make a change to the table. Then reload the information and put the foreign key back on. In this case you should probaly use alter table instead of drop and recreate but if you don't you may end up with id numbers that are not the same as they were originally and thus now the orders will reference the wrong ids. This can be done safely but you would have to do it very carefully and with a lot of thought as to the consequences.
by using On Delete Cascade
Related
I'm having a bit of an issue with circular foreign keys. I have a table posts with a uid column that is a BIGINT NOT NULL PRIMARY KEY, and I need to reference that in the last_seen_post column of my users table. The problem is that there's a sender_id column in posts that references users(user_id), meaning that I can't use both foreign keys at the same time because depending on the order of table definition, one of them will not be defined. Any fixes other than to drop the foreign key on the last_seen_post column?
I really would rather avoid dropping either foreign keys because the data integrity for this backend is mission critical. I know I could probably make another table to achieve this, but I was really hoping to get away with this since it's way cheaper in terms of space and search time
For context, the last_seen_post column is supposed to help the backend figure out what the user's "feed" is, i.e. the collection of posts from users they follow that they have not downloaded yet.
Alright, I figured it out, so I'm gonna leave the solution here if others need it in the future. The easiest thing to do is to create the column without the foreign key constraint and then do ALTER TABLE yourtbl ADD FOREIGN KEY (yourcolumn) REFERENCES othertbl(othercolumn); once both tables have been created!
I'm not sure what is the best way to structure my question.
I have a table with foreign key column in it. By default the foreign key is set to NOT NULL and I want to keep it that way for now, because maybe this will be the final result. But for now there could be records that don't need (and have) foreign keys values and I want to distinct them somehow so it is as clear as possible that these records are something different from the other.
I tried but as it seems I can not use negative numbers for bigint which is the value of the foreign key in my SQL Server table. I guess this is pretty standard stuff so what is the best thing to do in this situation besides making the foreign key to NULL?
Not sure why HABO didn't make that the answer, because that's pretty much your only option.
Make it NULL
Create a row in the referenced table and set it to TBD or whatever moniker you prefer and use the ID from that instead of NULL
If you have records that do not need an FK and never will, then you should set the column to NULL, else use a temp value.
You cannot use a negative value because you MUST reference something in the foreign table if you have a foreign key constraint.
Foreign key constraints enforces you to refer an existing PK of the other table.
One way not mentioned yet is to drop the constraint for now :
ALTER TABLE YourTable
DROP CONSTRAINT fk_something
I have created tables in sql server. And i have also inserted data/rows in that tables.
Now i want to make relationship among them means i want to create foreign key constraints among them, is it possible ?
Whenever i try to create relationship among table a problem is occured. "Saving changes is permitted, The changes you made required table to re-created and dropped"
Please suggest me what should i do to make relationship(foreign key) among them ?
My Child table design is this
this is my parent table:-
please now right what alter query i should write..?
You can try this link
"Error message when you try to save a table in SQL Server 2008: "Saving changes is not permitted"
Another solution is below.
I think the problem is because of a feature when using the GUI. If you have a look at this link it shows you how to work round it. It is a feature which prevents you from dropping and recreating the table which is what SSMS does in the background when you click ok.
The code provided by the previous posted is the best way to do this.
You could do this with a script like this:
alter table ChildTable
add constraint FK_ChildTable_ColumnName foreign key (ColumnName) references ParentTable(PrimaryKeyColumnName)
[Edit] If I read your description correctly the script would be:
alter table emp
add constraint FK_emp_salary foreign key(salary) references testing(roll)
You can only add foreign constraints that aren't violated by existing data. You may also have to add suitable indices first, although this depends on the DBMS. In any case, first make sure your existing data is compatible with the foreign keys you want to introduce. In other words, if you were to create the foreign key first, and then insert the data, you should not produce any foreign key violations.
Imagine this setup:
create table ObservationType
(
ObservationTypeId int primary key identity(1,1),
Name nvarchar(32) not null
)
create table Observation
(
ObservationId int primary key identity(1,1),
ObservationTypeId int foreign key references ObservationType(ObservationTypeId),
Title nvarchar(32) not null,
Description nvarchar(1024) not null,
StudentId int foreign key references Student(StudentId)
)
create table Student
(
foo bar
)
Now imagine this is full of data, it's working fine. How do you deal when the user wants to delete an observation type? Do you automatically delete any observation that has that particular type as FK?
In the real world, how did you handle this situation?
In many cases, that's the right thing to do - that's why ON DELETE CASCADE exists.
This means that for the deleted row, any row in another table that is defined as such a foreign key on that row will also be deleted.
The question that you need to ask is whether it is something that the user will really want? Does it make sense within the application domain to perform such deletes? Ask your user/s what they expect to happen if they delete an observations type - what do they think should happen to the existing observations.
Sometimes, it is better to go with a soft delete (marking a row with a delete status in a status field), so you can recover/undelete. This is not without its share of problems.
add a cascade delete to the foreign key? also, do you really want to allow real deletion from your database? why not just mark them as inactive?
Though it exists and can be useful, I wouldn't recommend setting cascade delete. I do agree, however, that soft-deletes can be a good thing.
However, for what you want, why not create a procedure that
deletes the appropriate Observation records
deletes the ObservationType
logs (ActivityLog?) what has been deleted and why (a comment). Don't need to store entire set of deleted data, but just enough for compliance (aka SOX). Who, what, when.
I prefer using 'soft' deletes if possible. Which means having Deleted bit column on a table.
So, when you delete you would actually run update statement on the table to set Deleted to 1.
However, if I wanted to delete rows for sure, I would use explicit delete statement, rather than ON DELETE CASCADE foreign keys.
delete Observation
where ObservationTypeId = 1
delete ObservationType
where ObservationTypeId = 1
I try to avoid using implicit ON DELETE CASCADE as it can lead to hidden dangerous unexpected deletes.
If all database is built on cascade delete foreign key, somebody by mistake can delete content of whole database just by running delete against one table that is referenced in all other tables. So to put it shortly I find ON DELETE CASCADE to be a bug prone solution.
Do i need to setting the foreign key for this situation ?
i'm weak in database design, especially in mysql.. may i know if i want to setting foreign keys for them, what should i setting for them ? in case if the people delete... all referral to people_id will delete together, is it possible to set while the table is too many ?
Thx for reply
Yes. Foreign key constraints enforce referential integrity, a key tenet of ensuring that your data is reliable and of high quality. Otherwise, your people_address table could reference a people_id value that doesn't exist in the people table, and would be an orphan. A foreign key constraint would prevent that from happening.
So, just do it. There's really no good reason not to.
Define foreign keys such as the following on the people_email table:
ALTER TABLE people_email ADD CONSTRAINT FOREIGN KEY (people_id) REFERENCES people (id) ON DELETE CASCADE;
This will mean that you cannot enter a record in people_email where the people_id in that table does not exist in people. Also, if you delete the parent row in people, the rows referencing it in people_email with get automatically deleted.
I personally prefer to manually delete all the rows from the child tables and not use cascade deletes though. It's a bit of extra app dev work, but it makes me feel safer and also allows me some control over locking and ensuring that queries are as efficient as possible.