Cascade Update & Delete - sql-server

I have a large database and I didn't add cascade on update/delete.
Can we do it with T-SQL without deleting and then recreating all the FK objects?

You should drop and recreate foreign keys.
this is the only way.
but you can use sys.foreign_keys and sys.foreign_key_columns to get the FK name and columns.
then you can write a loop to fetch names and columns and drop an recreate it with cascade option in every time loop executed.

Related

Delete rows from multiple joined tables

I have a problem with removing rows from multiple joined tables in SQL Server.
This is my script:
DELETE d, di, dis
FROM Data d
JOIN DataItem di ON di.DataId = d.DataId
JOIN DataItemSend dis ON dis.DataItemId = di.DataItemId
WHERE d.CardId = 1555
But this syntax is not correct and commas on first line are underlined. How can I solve this problem?
SQL Server does not support deleting from multiple tables at once - unlike MySQL for example.
The way your query is built, however, makes it looks like you could just set up proper foreign keys between the tables, with the on delete cascade option, like so:
alter table DataItem
add constraint fk_DataItem_Data
foreign key (DataId) references Data(DataId)
on delete cascade
;
alter table DataItemSend
add constraint fk_DataItemSend_DataItem
foreign key (DataItemId) references DataItem(DataItemId)
on delete cascade
;
With this set up in place, you can just delete from the top-parent table:
delete from Data where CardId = 1555
... And rest assured that all related records in the children table will be deleted.

Foreign Key with wordpress

I have a table (multisite network) where I use blog_id as one of the columns which is also needed on some of my custom php functions. Until now, I haven't used FK which should be appropriate for my tables.
So, can I FK to wordpress wp_blogs table? if yes, if ever I delete that blog will it also delete the entries on my other tables that references wp_blogs?
CREATE TABLE wp_blogs (blog_id INT NOT NULL...)
FOREIGN KEY (blog_id)
REFERENCES wp_options(blog_id)
ON DELETE CASCADE;
If you created a table like above then every time when blog_id will remove from wp_options then all rows from wp_blogs will remove too.
When you remove rows from wp_blogs then no rows won't remove from wp_options
Read about ON DELETE CASCADE in MySQL documentation.

Rename table in Sql Server and updating references

Hi I need to rename a table, and add some columns to it.
This table has a PK column (Id) and a Self-referencing column (ParentId). These constraints use the old table name in their names.
There are also other tables that use this tables PK as foreign keys.
So, what would be the correct way to do this, asssuming that I need to rename TableA->TableB?
Drop constraints in all tables that reference TableA.Id
sp_rename 'dbo.TableA', 'TableB'
Add constraints that were dropped with new names?
Or, there is some other way?

Cannot truncate table because it is being referenced by a FOREIGN KEY constraint

I get the following message even when the table that references it is empty: "Cannot truncate table 'dbo.Link' because it is being referenced by a FOREIGN KEY constraint" Doesn't seem to make much sense why this is occurring. Any suggestions?
In SQL Server a table referenced by a FK cannot currently be truncated even if all referencing tables are empty or the foreign keys are disabled.
You need to use DELETE (may require much more logging) or drop the relationship(s) prior to using TRUNCATE and recreate them afterwards or see the workarounds on this connect item for a way of achieving this using ALTER TABLE ... SWITCH
You cannot truncate a table which has an FK constraint on it. As workaround, you could:
1/ Drop the constraints
2/ Trunc the table
3/ Recreate the constraints.
Here it is the associated T-SQL script, supposing you have 2 tables called MyTable and MyReferencedTable:
-- Remove constraint
IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE name = 'FK_MyReferencedTable_MyTable')
BEGIN
ALTER TABLE dbo.MyReferencedTable
DROP CONSTRAINT FK_MyReferencedTable_MyTable
END
-- Truncate table
TRUNCATE TABLE dbo.MyTable
-- Re-Add constraint
IF NOT EXISTS(SELECT 1 FROM sys.foreign_keys WHERE name = 'FK_MyReferencedTable_MyTable')
BEGIN
ALTER TABLE dbo.MyReferencedTable
WITH CHECK ADD CONSTRAINT [FK_MyReferencedTable_MyTable] FOREIGN KEY(ListingKey)
REFERENCES dbo.MyTable (ListingKey)
END
Execute the following query to search any constraint:
use MyDatabase
select c.name as c_name, t.name as t_name
from sys.key_constraints c
join sys.tables t on t.object_id = c.parent_object_id
If any constraint found on your table, remove it.
If you are receiving this error and you need to truncate the table then alternative solution could be that you can drop and re-create the table along with primary/other_keys/indexes/triggers. Please make sure that you don't need to the data in that table.
This soulution is working like a charm for me and hardly took a minute to finish. I am doing it for masking purpose.
Not for SQL Server but MySQL only.
Instead of deleting or recreating the constraint, I prefer this simpler way.
Disable the constraint validation by executing the following query first :
SET FOREIGN_KEY_CHECKS=0;
Then truncate your tables
And finally, reactivate the constraint validation :
SET FOREIGN_KEY_CHECKS=1;
Thats a common solution when you migrate databases, so you don't have to worry about the order the tables are inserted in.

SQL Server - Maintain Referential Integrity without CASCADE and INSTEAD OF trigger

I have a table (TableB) that has a foreign key relationship with a parent table (TableA).
When I delete a record in Table A, I want to preserve referential integrity by deleting all records in TableB that reference the deleted record in TableA.
Normally I would ON DELETE CASCADE. However due to the table structure and the overprotective safeguards against multiple cascade paths in SQL Server, this is not possible for this specific relationship.
I also cannot use an INSTEAD OF trigger as TableA itself has a CASCADE foreign key relationship on it.
What I'm thinking of doing is changing the relationship between TableA and TableB to ON DELETE SET NULL, then creating an AFTER trigger to cleanup the NULL records in TableB.
Are there better ways of dealing with this scenario?
Can you change the other constraint that is preventing you from adding this one as ON DELETE CASCADE?
Can you add a DeleteMe column, then issue an UPDATE A SET DeleteMe = 1, then use an after trigger to delete Table B rows first, then the requested table A rows?
Can you split or merge tables (vertically, that is) in some way that separates their mutually exclusive dependencies?

Resources