How can I alter a primary key constraint using SQL syntax? - sql

I have a table that is missing a column in its primary key constraint. Instead of editing it through SQL Server, I want to put this in a script to add it as part of our update scripts.
What syntax can I use to do this? Must I drop and recreate the key constraint?

Yes. The only way would be to drop the constraint with an Alter table then recreate it.
ALTER TABLE <Table_Name>
DROP CONSTRAINT <constraint_name>
ALTER TABLE <Table_Name>
ADD CONSTRAINT <constraint_name> PRIMARY KEY (<Column1>,<Column2>)

PRIMARY KEY CONSTRAINT cannot be altered, you may only drop it and create again. For big datasets it can cause a long run time and thus - table inavailability.

Performance wise there is no point to keep non clustered indexes during this as they will get re-updated on drop and create.
If it is a big data set you should consider renaming the table (if possible , any security settings on it?), re-creating an empty table with the correct keys migrate all data there.
You have to make sure you have enough space for this.

In my case, I want to add a column to a Primary key (column4).
I used this script to add column4
ALTER TABLE TableA
DROP CONSTRAINT [PK_TableA]
ALTER TABLE TableA
ADD CONSTRAINT [PK_TableA] PRIMARY KEY (
[column1] ASC,
[column2] ASC,
[column3] ASC,
[column4] ASC
)

PRIMARY KEY CONSTRAINT can only be drop and then create again.
For example in MySQL:
ALTER TABLE table_name DROP PRIMARY KEY;
ALTER TABLE table_name ADD PRIMARY KEY (Column1,Column2);

you can rename constraint objects using sp_rename (as described in this answer)
for example:
EXEC sp_rename N'schema.MyIOldConstraint', N'MyNewConstraint'

Related

Alter datatype of clustered index primary key in table

I have a table with
CONSTRAINT [user_const] PRIMARY KEY CLUSTERED ([id] ASC, [group] ASC)
I want to change the datatype of group to NVARCHAR from NCHAR.
Simply running
ALTER TABLE [dbo].[user] ALTER COLUMN [group] NVARCHAR (50) NOT NULL;
gives me an error:
The object 'user_const' is dependent on column 'group'.
CHECK NOCHECK does not work as
This action applies only to foreign key and check constraints.
So, I thought I should drop the constraint and recreate it
ALTER TABLE [dbo].[user] DROP CONSTRAINT [user_const];
ALTER TABLE [dbo].[user] ALTER COLUMN [group] NVARCHAR (50) NOT NULL;
ALTER TABLE [dbo].[user] ADD CONSTRAINT CONSTRAINT [user_const] PRIMARY KEY CLUSTERED ([id] ASC, [group] ASC)
But error reads
Tables without a clustered index are not supported in this version of SQL Server.
How can I alter the datatype of a column which is a primary key constraint?
Azure does not support tables without clustered indexes. Read here
http://msdn.microsoft.com/library/azure/ee336245.aspx#cir
In order to change the data type, you are going to have to create a second table with the new datatypes, move the data over, and then rename.
Since you're changing the primary key, you're effectively rebuilding the entire table anyway, so you might as well build a new table with the new format and rename to get the name right. I haven't run this so it might need a little tweaking, but something like this:
-- check to see if we've already run this script and swap table names and just run it again with the old data if we have
IF EXISTS (SELECT * FROM SysObjects WHERE name='MyTable_bak' AND type='U')
IF EXISTS (SELECT * FROM SysObjects WHERE name='MyTable' AND type='U')
DROP TABLE MyTable
ELSE
EXEC sp_rename 'MyTable', 'MyTable_bak'
GO
-- create the new table with updated columns
CREATE TABLE MyTable (
[id] BIGINT NOT NULL,
[group] NVARCHAR(50) NOT NULL,
CONSTRAINT PK_MyTable PRIMARY KEY CLUSTERED
(
[id] ASC, [group] ASC
))
GO
-- copy in the data from the old version
INSERT MyTable([id],[group])
SELECT [id],[group]
FROM MyTable_bak
GO
-- drop the old table (maybe wait to do this until testing is complete?)
DROP TABLE MyTable_bak

Dropping and adding a constraint in sql

I want to drop and add a constraint
ALTER TABLE [dbo].[Entity] DROP CONSTRAINT [x_UpdateDate1]
ALTER TABLE [dbo].[Entity] ADD CONSTRAINT [x_UpdateDate1] DEFAULT ([dbo].[GETSYSTEMDATE]()) FOR [CreateDate]
I want to find the alternative for this. As dropping and adding a constraint is not advisable. Is there any better way to handle
No. You cannot alter a constraint, you need to drop it and then recreate it just as you did.
No, there's no other way than to drop and re-create constraints (check also sqlauthority.com blog entry)
You can disable constraints with:
ALTER TABLE tbl NOCHECK CONSTRAINT all
and then turn them back on with:
ALTER TABLE tbl WITH CHECK CHECK CONSTRAINT all
of course this SQL turns off ALL constraints on the table but you can specify an individual constraint like this:
ALTER TABLE tbl NOCHECK CONSTRAINT Constraint1

How to Write a Script to add extra columns for my primary key

I have the following table in SQL Server 2008 R2
Now I need to write a script to add a new column cusomerVLANID as part of the primary key, so that the three columns becomes the primary key, is there a way to write such script.
Second thing I want to write a script to remove the Allow Null, check box from the CustomerVLANID columns ?
Thanks
ALTER TABLE <Table_Name>
DROP CONSTRAINT <constraint_name>
ALTER TABLE <Table_Name>
ADD CONSTRAINT <constraint_name> PRIMARY KEY ([ID], [CustomerName], [CustomerVLANSID])
Run this statement separately to set up the NOT NULL constraint:
ALTER TABLE <Table_Name>
ALTER COLUMN [CustomerVLANSID] INT NOT NULL
alter table TABLE1
alter column [CustomerVLANID] int not null
I hope this helps,
-Thomas
RosSQL.blogspot.com

How to drop more than one constraint at once (Oracle, SQL)

I'm changing constraints in my database and I need to drop some of them. I know that for a single constraint, the command is following:
ALTER TABLE tblApplication DROP CONSTRAINT constraint1_name;
However, when I try
ALTER TABLE tblApplication DROP (
CONSTRAINT constraint1_name,
CONSTRAINT constraint2_name,
CONSTRAINT constraint3_name
);
it doesn't work and I need to do:
ALTER TABLE tblApplication DROP CONSTRAINT constraint1_name;
ALTER TABLE tblApplication DROP CONSTRAINT constraint2_name;
ALTER TABLE tblApplication DROP CONSTRAINT constraint3_name;
Is there a way to remove more than one constraint in a single command? I'd like to avoid repeating ALTER TABLE tblApplication, just like with the ADD command:
ALTER TABLE tblApplication ADD (
CONSTRAINT contraint1_name FOREIGN KEY ... ENABLE,
CONSTRAINT contraint2_name FOREIGN KEY ... ENABLE,
CONSTRAINT contraint3_name FOREIGN KEY ... ENABLE
);
Yes you can. You just need to repeat 'drop constraint' per constraint. e.g.
alter table t1
drop constraint fk1
drop constraint fk2
/
Edit: I tested this against Oracle 11, and it worked fine. Don't know about older versions.
There is an alternative form to drop constraints related to a column in a table, also dropping the column with CASCADE:
ALTER TABLE table1 DROP (columnName) CASCADE CONSTRAINTS;
It is tested on Oracle 11g
example: we can drop constraints in MySQL by creating constraints to the variables like this way.
create table sample(id int, name varchar(30), marks int, constraint uid unique(id), constraint un unique(name));
alter table sample drop constraint uid, drop constraint un;
Yes, we can drop multiple at once:
ALTER TABLE TABLE NAME
DROP CONSTRAINTS CONSTRAINT VALUE
DROP CONSTRAINTS CONSTRAINT VALUE;

Dropping then adding a constraint fails in oracle

I'm trying to move a primary key constraint to a different column in oracle. I tried this:
ALTER TABLE MY_TABLE
DROP CONSTRAINT c_name;
ALTER TABLE MY_TABLE
ADD CONSTRAINT c_name PRIMARY KEY
(
"COLUMN_NAME"
) ENABLE;
This fails on the add constraint with an error saying the the constraint already exists even though i just dropped it. Any ideas why this is happening
If the original constraint was a primary key constraint, Oracle creates an index to enforce the constraint. This index has the same name as the constraint (C_NAME in your example). You need to drop the index separately from the constraint. So you will need to do a :
ALTER TABLE <table1> DROP CONSTRAINT C_NAME;
DROP INDEX C_NAME;
ALTER TABLE <table1> ADD CONSTRAINT C_NAME PRIMARY KEY
( COLUMN_2 ) ENABLE;
The safest way is to first add a unique index. Try this:
create unique index new_pk on <tabname> (column_2);
Then drop the old PK:
alter table <tabname> drop primary key drop index;
(Optional) Rename the index:
alter index new_pk rename to c_name;
And then add the PK again indicating the index to be used:
alter table <tabname> add constraint c_name
primary key (column_2) using index c_name;
I don't know if this is a similar problem but, in DB2, you have to actually commit following the alter table statement. Otherwise it's still hanging around.