Oracle drop constraint cascade equivalent in Sql Server - sql-server

In Oracle, to drop the constraint PK_SAI I use the syntax:
ALTER TABLE "SAISIE"
DROP CONSTRAINT "PK_SAI" CASCADE;
What is the equivalent of this in SQL Server?

You are thinking of the CASCADE feature on FOREIGN KEY constraints, in relation to actual DELETE statements.
ALTER TABLE t2 add constraint FK_T2 foreign key(t_id) references t(id)
ON DELETE CASCADE;
Dropping a constraint with CASCADE does not delete any rows.
DELETE deletes rows, if you have enabled ON DELETE CASCADE.
Dropping the constraint simply drops the constraint (and associated indexes and dependent constraints), not data rows. In SQL Server ALTER TABLE ... I am not aware that there is a "CASCADE" option as in Oracle.
From Oracle docs http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_3001.htm#i2103845 for the ALTER TABLE statement:
CASCADE Specify CASCADE if you want all other integrity constraints that depend on the dropped integrity constraint to be dropped as well.

Related

Is there a way to turn off foreign key constraints at database level?

We need to use existing sql to create a bunch of tables and this sql includes ALTER TABLE statements to add in foreign keys. When we run this block of SQL, however, errors are thrown because tables needed for the foreign keys haven't been created yet (they are later on in the block of SQL).
Is there a way to turn off foreign key constraints at database level? (versus at table level) We just need to create all of the tables and foreign keys and then turn it back on.
Thanks!
To disable foreign key constraints when you want to truncate a table:
Use FOREIGN_KEY_CHECKS
SET FOREIGN_KEY_CHECKS=0;
and remember to enable it when you’re done:
SET FOREIGN_KEY_CHECKS=1;
Or you can use DISABLE KEYS:
ALTER TABLE table_name DISABLE KEYS;
Again, remember to enable if thereafter:
ALTER TABLE table_name ENABLE KEYS;
Note that DISABLE KEYS does not work on InnoDB tables as it works properly for MyISAM.
Use ON DELETE SET NULL
If you don’t want to turn key checking on and off, you can permanently modify it to ON DELETE SET NULL:
--Delete the current foreign key first:
ALTER TABLE table_name1 DROP FOREIGN KEY fk_name1;
ALTER TABLE table_name2 DROP FOREIGN KEY fk_name2;
--Then add the foreign key constraints back
ALTER TABLE table_name1
ADD FOREIGN KEY (table2_id)
REFERENCES table2(id)
ON DELETE SET NULL;
ALTER TABLE tablename2
ADD FOREIGN KEY (table1_id)
REFERENCES table1(id)
ON DELETE SET NULL;

Delete data with SQL constraints

I have the following:
DELETE FROM ContactBase
DELETE FROM AccountBase
It errors with:
The DELETE statement conflicted with the REFERENCE constraint "account_primary_contact". The conflict occurred in database "BMBLANK_MSCRM", table "dbo.AccountBase", column 'PrimaryContactId'.
The DELETE statement conflicted with the REFERENCE constraint "account_contacts". The conflict occurred in database "BMBLANK_MSCRM", table "dbo.ContactBase", column 'AccountId'.
I understand because of the constraint I need to delete the data in a particular order, but if I reverse it:
DELETE FROM AccountBase
DELETE FROM ContactBase
It just reverses the error messages:
The DELETE statement conflicted with the REFERENCE constraint "account_contacts". The conflict occurred in database "BMBLANK_MSCRM", table "dbo.ContactBase", column 'AccountId'.
The DELETE statement conflicted with the REFERENCE constraint "account_primary_contact". The conflict occurred in database "BMBLANK_MSCRM", table "dbo.AccountBase", column 'PrimaryContactId'.
How do I empty these tables?
Thanks
First drop the constraints , delete the data and add them again:
ALTER TABLE AccountBase
DROP CONSTRAINT account_contacts;
ALTER TABLE ContactBase
DROP CONSTRAINT account_primary_contact;
DELETE FROM ContactBase;
DELETE FROM AccountBase;
ALTER TABLE AccountBase
ADD FOREIGN KEY (account_contacts)
REFERENCES ContactBase(PrimaryContactId);
ALTER TABLE ContactBase
ADD FOREIGN KEY (account_primary_contact)
REFERENCES AccountBase(AccountId);
Maybe I mixed them, its confusing without the tables DDL's , so if I did just adjust it.
You can generate a script of the constraints, drop the constraints, delete from tables, then use the script to recreate the constraints.
How to generate all constraints scripts
Drop the constraints and then delete the data from the tables. Then, if needed, add the constraints again.

Update even though using constraints

I'm trying to update a value (small spelling error) in the SQL Server 2014 database.
I do like this:
update t_Table set funID = 'References' where funID = 'Referencies'
When doing this I get the error
The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_t_Table_Language_t_Table". The conflict occurred in database "db", table "dbo.t_Table".
If updating the foreign key, I get a similar error.
Is there any way to update all values at the same time?
I have a vague memory of someone showing a way to do this in management studio but I do not recall how.
Enable update cascade on the foreign key
ALTER TABLE t_Table_Language DROP CONSTRAINT FK_t_Table_Language_t_Table
ALTER TABLE t_Table_Language ADD CONSTRAINT FK_t_Table_Language_t_Table
FOREIGN KEY (funID) REFERENCES t_Table(funID)
ON UPDATE CASCADE
EDIT:
Or the other way around, i'm not sure which table has the foreing key
ALTER TABLE t_Table DROP CONSTRAINT FK_t_Table_Language_t_Table
ALTER TABLE t_Table ADD CONSTRAINT FK_t_Table_Language_t_Table
FOREIGN KEY (funID) REFERENCES t_Table_Language(funID)
ON UPDATE CASCADE
Then do the update on the referenced table (the master table).
UPDATE t_Table_Language
SET funID = 'References'
WHERE funID = 'Referencies'

How to DELETE without ON DELETE CASCADE (conflict REFERENCE constraint)

I have a gigantic legacy database with a table that has multiple foreign keys pointing to one other table and with not a single cascade in sight, similar to sample tables below:
create table Users (
Id int primary key identity,
Name varchar(max)
)
create table Products (
Id int primary key identity,
Name varchar(max),
CreatedBy int foreign key references Users(Id),
UpdatedBy int foreign key references Users(Id)
)
insert into Users values('Bar')
insert into Users values('Baz')
insert into Products values('Foo', 1, 2)
I need to be able to to delete some of the old data, but it of course throws reference exceptions:
delete from Users where Name='Bar'
The DELETE statement conflicted with the REFERENCE constraint "FK__Products__Create__1AD3FDA4". The conflict occurred in database "Foo", table "dbo.Products", column 'CreatedBy'.
Due to the sheer complexity of the database I can't predelete all of the references, so I'm trying to add temporary foreign keys programmatically with cascades set to resolve them. However, for this particular table that has multiple foreign keys to one other table, this results in cycles or multiple cascade paths on the second UpdatedBy alter:
alter table Products add foreign key (CreatedBy) references Users(Id) on delete cascade
alter table Products add foreign key (UpdatedBy) references Users(Id) on delete cascade
Introducing FOREIGN KEY constraint 'FK__Products__Update__1DB06A4F' on table 'Products' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
How can I make delete from Users where work while maintaining referential integrity, either by somehow getting around multiple cascade path issues or otherwise?
Personally I would not do this (I would pre-delete all the referenced data and manually check the integrity). See: Can foreign key constraints be temporarily disabled using T-SQL?
Quote:
-- disable all constraints
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
Delete your data once the constraints are disabled, but remember to turn them back on again afterwards!
-- enable all constraints
EXEC sp_msforeachtable #command1="print '?'", #command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
Also note that the stored procedure sp_msforeachtable is undocumented and may disappear in future releases of SQL Server.
If you'd rather not blanket-disable constraints (perhaps you have a list of the tables that apply) then simply disable them as you can see in the code above.
ALTER TABLE [Products] NOCHECK CONSTRAINT ALL
DELETE FROM [Users] where Name='Bar'
ALTER TABLE [Products] WITH CHECK CHECK CONSTRAINT ALL
All credit goes to kristof's answer. Please up vote!

How to recheck primary/foreign key constraint for data already in the table in sql server?

I have a table in SQL Server 2005 with a foreign key and it was disable for huge data loading, and then re-enabled:
Example:
alter table table1 nocheck constraint fk_1
go
lots of inserts...
go
alter table table1 check constraint fk_1
go
Now, the question: is there a way to re-check this just inserted data?
The syntax looks a little silly with the word "check" repeated, but what you want is:
alter table table1 with check check constraint fk_1
go
Adding the "with check" option will validate existing data against the constraint. Doing this will also prevent the constraint from becoming untrusted.
If any existing data violates the constraint, you'll get an error that will look like this:
The ALTER TABLE statement conflicted with the CHECK constraint "fk_1".

Resources