Dropping table in SQL with Constraint - sql

I'm trying to drop a table in Northwind, and I'm getting:
ALTER TABLE DROP COLUMN Region failed because one or more objects access this column.
I'm using:
use [NorthWind]
go
alter table dbo.Customers
drop column Region
I guess it's because there is a constraint on the column Region. How do I find out which constraint I need to remove?

EXEC sp_MSforeachtable #command1="ALTER TABLE ? NOCHECK CONSTRAINT ALL"
GO
OR
ALTER TABLE table_Name NOCHECK CONSTRAINT all
OR
ALTER TABLE table_Name NOCHECK CONSTRAINT constraint_name
Then try with your SQL.
Please use this when you really want to drop constraints no matter other tables affected.
If disabling the constraints is not enough, you will have to drop the constraints.

You must drop Constraint first and then drop the table.If you have SQL Server Management Studio you can select the constraint and delete it using GUI. Or you can use command line to drop your constraints
How to remove foreign key constraint in sql server?. Taken from this answer
ALTER TABLE <TABLE_NAME> DROP CONSTRAINT <FOREIGN_KEY_NAME>

If you want to go via Sql Server Management Studio on the object explorer window, right click on the object you want to drop,then click view dependencies.

First, you should know the ForeignKey - Constraint. After that, you must drop it.
Something like this:
-- looking for the Constraint's name related the dbo.Customers table
SELECT Table_Name,Constraint_Name
FROM Information_Schema.CONSTRAINT_TABLE_USAGE
WHERE Table_Name 'Customers'
-- Drop/Delete the founded constraint
ALTER TABLE [dbo].[Customers] DROP CONSTRAINT [FOREIGN_KEY_NAME]
Then, you'll run your actual script.

Related

Using the SQL Server 2016 syntax how to use drop constraint 'if exists' when the table itself may or may not exist?

I've researched how to test for the existence of a table or constraint when deleting database items in SQL Server 2016 and learned that the 'if exist' syntax can be used for this. But I haven't worked out how to delete a table's constraints, followed by deleting the table itself, in cases where the table itself may or may not exist without the script erroring.
-- Drop TABLE1
alter table TABLE1 drop constraint if exists F_TABLE1_COLUMN1
go
alter table TABLE1 drop constraint if exists F_TABLE1_COLUMN2
go
alter table TABLE1 drop constraint if exists P_TABLE1_COLUMN2
go
drop table if exists TABLE1
go
In this example the script will error attempting to delete the constraint if the table does not exist.
How should I script this?
You can check to see if a table exists as stated here
add your code for dropping constraint within the block as :
IF (EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = <table_name>))
BEGIN
ALTER TABLE <table_name>
DROP CONSTRAINT <Constraint_name>;
END
From SQL Server 2016 onwards, you have DROP IF EXISTS syntax. First check the existance of the table, before going ahead with dropping of constraint, Table.
IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID('<TableName>'))
BEGIN
ALTER TABLE <TableName> DROP CONSTRAINT IF EXISTS <CONSTRAINTNAME>;
DROP TABLE IF EXISTS <TableName>;
END
GO
Also, if you are planning to drop the table, you dont need to drop the constraint. You can simply drop the table directly. Below would suffice.
IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID('<TableName>'))
BEGIN
DROP TABLE IF EXISTS <TableName>;
END
GO
But, I would suggest you to check and drop the foreign keys associated with this table and then drop this table. Otherwise you will get error. You can check the foreign keys associated with the table from the below script. First you need to drop them, before dropping the tables.
EXEC sp_fkeys [ #pktable_name = ] 'pktable_name'
First, you don't need to delete the constraints separately. They will be deleted with the table.
You can delete each constraint independently using try/catch blocks.
So the equivalent of your if exists is:
begin try
alter table TABLE1 drop constraint F_TABLE1_COLUMN1;
end try
begin catch
end catch;
You can also delete the table an all associated constraints using dynamic SQL:
exec sp_executesql 'drop table TABLE1';

SQL Server Change Primary Key Data Type

I am working on SQL Server 2012:
I have a table with a primary key column as INT. I need to change this to a GUID.
Do I alter the table and remove int column as primary key?
Add the GUID column and set it as Primary and drop the old INT column?
Thank you.
You can't change primary key column,unless you drop it..Any operations to change its data type will lead to below error..
The object 'XXXX' is dependent on column 'XXXX'.
Only option is to
1.Drop primary key
2.change data type
3.recreate primary key
ALTER TABLE t1
DROP CONSTRAINT PK__t1__3213E83F88CF144D;
GO
alter table t1
alter column id varchar(10) not null
alter table t1 add primary key (id)
From 2012,there is a clause called (DROP_EXISTING = ON) which makes things simple ,by dropping the clustered index at final stage and also keeping old index available for all operations..But in your case,this clause won't work..
So i recommend
1.create new table with desired schema and indexes,with different name
2.insert data from old table to new table
3.finally at the time of switch ,insert data that got accumulated
4.Rename the table to old table name
This way you might have less downtime
You can change the date type of the primary key in three steps
Step 1 :- Drop the constraint associated with the Primary key
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;
Step 2 :- Alter the Primay key column to a valid primary key data type
ALTER TABLE table_name
ALTER COLUMN pk_column_name target_data_type(size) not null;
Step 3 :- Make the altered column primary key again
ALTER TABLE table_name
ADD PRIMARY KEY (pk_column_name);
PS :-
You can get the Constraint name from the error message when you try to alter the
pk_column
If you already have data in the pk_column make sure the source and target data type of the column both can be used for the existing data. else another two steps would be needed to move the existing data to a temporary column and then perform the steps and bring back that data after vetting and dropping that temporary column.
Below is a script I wrote to help us deploy a change to primary key column data type.
This script assumes there aren't any non-primary key constraints (e.g. foreign keys) depending on this column.
It has a few safety checks as this was designed to be deployed to different servers (dev, uat, live) without creating side effects if the table was somehow different on a server.
I hope this helps someone. Please let me know if you find anything wrong before down-voting. I'm more than happy to update the script.
IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS C WITH (NOLOCK) WHERE C.TABLE_CATALOG = '<<DB>>' AND C.TABLE_SCHEMA = 'dbo' AND C.TABLE_NAME = '<<Table>>'
AND C.COLUMN_NAME = '<<COLUMN>>' AND C.DATA_TYPE = 'int') -- <- Additional test to check the current datatype so this won't make unnecessary or wrong updates
BEGIN
DECLARE #pkName VARCHAR(200);
SELECT #pkName = pkRef.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pkRef WITH (NOLOCK)
WHERE pkRef.TABLE_CATALOG = '<<DB>>' AND pkRef.TABLE_SCHEMA = 'dbo' AND TABLE_NAME = '<<Table>>'
IF(#pkName IS NOT NULL)
BEGIN
-- Make sure the primary key name is the one you are going to use in script beyond this point.
IF(#pkName != '<<PRIMARY KEY NAME>>')
BEGIN
RAISERROR ('Unexpected primary key name - The primary key found has a different name than expected. Please update the script.', 16, 1);
RETURN;
END
ALTER TABLE dbo.<<Table>>
DROP CONSTRAINT <<PRIMARY KEY NAME>>; -- Note: this is not a string or a variable (just type the PK name)
SELECT 'Dropped existing primary key';
END
ALTER TABLE dbo.<<Table>> ALTER COLUMN ID BIGINT
SELECT 'Updated column type to big int';
ALTER TABLE dbo.<<Table>>
ADD CONSTRAINT <<PRIMARY KEY NAME>> PRIMARY KEY CLUSTERED (<<COLUMN>>);
SELECT 'Created the primary key';
END
ELSE
BEGIN
SELECT 'No change required.';
END
In case other tables reference your PK with indexed FK's, these are the steps you must follow.
In this example, the main table's called Main, the single referencing table Reference. I'm changing the datatype to NVARCHAR(7). To use it:
Find/replace all these table names with your own;
Modify the data type;
You might also need to separately find/replace the dbo schema;
I'm using syntax which includes constraint names - if you want, also update these to your preferred naming conventions.
ALTER TABLE dbo.Main ADD IdNew NVARCHAR(7);
UPDATE dbo.Main SET IdNew = Id;
-- For all tables with FK's to this Main:
ALTER TABLE dbo.Reference ADD MainIdNew NVARCHAR(7);
UPDATE dbo.Reference SET MainIdNew = MainId;
ALTER TABLE dbo.Reference DROP CONSTRAINT FK_Reference_MainId_Main_Id;
DROP INDEX IX_Reference_MainId ON dbo.Reference;
ALTER TABLE dbo.Reference DROP COLUMN MainId;
-- Until here
ALTER TABLE dbo.Main DROP CONSTRAINT PK_Main;
ALTER TABLE dbo.Main DROP COLUMN Id;
EXEC sp_rename 'dbo.Main.IdNew', 'Id', 'COLUMN';
ALTER TABLE dbo.Main ALTER COLUMN Id NVARCHAR(7) NOT NULL;
ALTER TABLE dbo.Main ADD CONSTRAINT PK_Main PRIMARY KEY (Id);
-- Again for all tables with FK's to this Main:
EXEC sp_rename 'dbo.Reference.MainIdNew', 'MainId', 'COLUMN';
ALTER TABLE dbo.Reference ADD CONSTRAINT FK_Reference_MainId_Main_Id FOREIGN KEY (MainId) REFERENCES dbo.Main(Id);
CREATE INDEX IX_Reference_MainId ON dbo.Reference(MainId);
Right in the table you want to change the PK type >> Modify. Go in the column, change the type and save. If you want to see the code for such a change, before saving, you can right-click >> "Generate Change Script ..".
Using Microsoft SQL Server Management Studio do the following:
Open table Design
Change the primary key column type or any other change which is also possible with this way
Right click on the design area and select Generate Change Script
Accept Validation Warning
Preview changes or save them in file.
Profit :)
This works for any change to the table, just bare in mind that SSMS creates a temporary second table to do the difficult changes like primary column type change.
This works for me in version 18.9 of the app.

SQL - Add Unique Constraint Failure

Trying to alter a table in SQL Server. I want to add a unique constraint to a column called Names in table ReportingItemNames:
ALTER TABLE ReportingItemNames
ADD CONSTRAINT UC_ReportingItemNames$Name UNIQUE ([ReportingItemNames,Name])
But I am getting this error:
Column name 'ReportingItemNames,Name' does not exist in the target table or view
Where am I going wrong?
Use this:
ALTER TABLE ReportingItemNames
ADD CONSTRAINT UC_ReportingItemNames UNIQUE ([Name])
You can refer to ALTER TABLE (Transact-SQL) documentation for more information.
Shouldn't it be:
ALTER TABLE ReportingItemNames
ADD CONSTRAINT UC_ReportingItemNames$Name UNIQUE ([Name])

How do I edit a table in order to enable CASCADE DELETE?

I have a table representing users. When a user is deleted I get:
DELETE statement conflicted with the REFERENCE constraint
Apparently, CASCADE DELETE is not as easy as I imagined in SQL Server, and the option needs to be added to the table.
The problem is: I cannot figure out how to add the CASCADE DELETE option.
I'm using: SQL Server 2008. Any ideas how to do this?
Read this Microsoft article first. Read Me. I use the GUI during design so here is a picture of how it is selected in SSMS.
The syntax added to the foreign key is " ON DELETE CASCADE "
Here's the way I would add the "cascading delete" feature to an existing foreign key in SQL Server Management Studio.
First, find your foreign key, and open it's "DROP and CREATE To" in a new Query window.
Then, just add "ON DELETE CASCADE" to the "ADD CONSTRAINT" command:
Then just hit hit the "Execute" button to run the query.
Job done !
Google ALTER TABLE DROP CONSTRAINT, then ALTER TABLE ADD CONSTRAINT:
ALTER TABLE
Here's a quick example:
CREATE TABLE A
(
ID INTEGER NOT NULL UNIQUE
);
CREATE TABLE B
(
ID INTEGER NOT NULL UNIQUE
CONSTRAINT fk__B__A
REFERENCES A (ID)
);
-- Oops! Forgot the CASCADE referential actions.
-- DROP the constraint then recreate it:
ALTER TABLE B DROP
CONSTRAINT fk__B__A;
ALTER TABLE B ADD
CONSTRAINT fk__B__A
FOREIGN KEY (ID)
REFERENCES A (ID)
ON DELETE CASCADE
ON UPDATE CASCADE;

Disable foreign key constraint on all tables didn't work

I try a lot of commands to disable tables constraints in my database to make truncate to all tables but still now it give me the same error:
Cannot truncate table '' because it is being referenced by a FOREIGN KEY constraint.
I try
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
EXEC sp_MSforeachtable "TRUNCATE TABLE ?"
And I tried this for each table
ALTER TABLE [Table Name] NOCHECK CONSTRAINT ALL
truncate table [Table Name]
ALTER TABLE [Table Name] CHECK CONSTRAINT ALL
and every time I have the previous error message. How can I solve this problem?
If you want to truncate the table, probably you have to drop the foreign keys and add them back. From here.
"You cannot use TRUNCATE TABLE on a table referenced by a FOREIGN KEY constraint; instead, use DELETE statement without a WHERE clause. Because TRUNCATE TABLE is not logged, it cannot activate a trigger."
Similar question here in SO.
I think is a rather bad idea. It isn't a good idea to blindly run those sort of SQL commands on ALL tables in your database.
What exactly are you trying to do?
If you want to create a copy of your Database (for example) with the same tables, with no data in them you can do that with SSIS package very easily (just make sure the COPY DATA) option is set to False
http://www.kodyaz.com/articles/transfer-sql-server-objects-task.aspx