Add primary key column in SQL table - sql-server

I am student of RDBMS.
I have very basic question let say I have one existing Table in SQL server. What will be script to alter table.
Drop Column 'RowId' if exist.
Drop contraint if exist.
Add one new column 'RowId' into table.
Make this column as primary key.
Autoincrement type int.

In SQL Server 2005 or newer, you could use this script:
-- drop PK constraint if it exists
IF EXISTS (SELECT * FROM sys.key_constraints WHERE type = 'PK' AND parent_object_id = OBJECT_ID('dbo.YourTable') AND Name = 'PK_YourTable')
ALTER TABLE dbo.YourTable
DROP CONSTRAINT PK_YourTable
GO
-- drop column if it already exists
IF EXISTS (SELECT * FROM sys.columns WHERE Name = 'RowId' AND object_id = OBJECT_ID('dbo.YourTable'))
ALTER TABLE dbo.YourTable DROP COLUMN RowId
GO
-- add new "RowId" column, make it IDENTITY (= auto-incrementing)
ALTER TABLE dbo.YourTable
ADD RowId INT IDENTITY(1,1)
GO
-- add new primary key constraint on new column
ALTER TABLE dbo.YourTable
ADD CONSTRAINT PK_YourTable
PRIMARY KEY CLUSTERED (RowId)
GO
Of course, this script may still fail, if other tables are referencing this dbo.YourTable using foreign key constraints onto the pre-existing RowId column...
Update: and of course, anywhere I use dbo.YourTable or PK_YourTable, you have to replace those placeholder with the actual table / constraint names from your own database (you didn't mention what they were, in your question.....)

Note: this answer was added before questions update
Add new column (note: you can only have one IDENTITY column per table)
Drop old primary key
Add new primary key
Drop old column if needed
Sample script:
CREATE TABLE whatever (
OldPKColumn uniqueidentifier NOT NULL,
CONSTRAINT PK_whatever PRIMARY KEY (OldPKColumn)
)
ALTER TABLE whatever
ADD RowId int NOT NULL IDENTITY (1,1);
ALTER TABLE whatever
DROP CONSTRAINT PK_whatever;
ALTER TABLE whatever WITH CHECK
ADD CONSTRAINT PK_whatever PRIMARY KEY CLUSTERED (RowId);
ALTER TABLE whatever
DROP COLUMN oldPKcolumn;
And a random thought... are you trying to reset an IDENTITY column?
If so, then use DBCC CHECKIDENT

Just a comment to improve these great answers (can't use comments yet - I'm one reputation point away from that privilege) and as future reference for myself:
A new IDENTITY (autonumber) column can be added and made the primary key in a single statement as well:
ALTER TABLE [TableName] ADD [ColumnName] int IDENTITY PRIMARY KEY;
I prefer not to bother with constraint names when it doesn't help.
You can specify seed (and increment) values between parantheses after the IDENTITY keyword.

Related

Adding AUTO_INCREMENT

I have a table where I've merged 2 tables into one.
One of the tables had an ID (primary key).
Now I got a merged table where some of the ID is 0.
I now try to restore and fill out the 0 with AUTO_INCREMENT so I
get a table with unique numbers (and not lose the one already there )
Someone got a god solution here ?
Firstly, the fact that you have a bunch of 0's in the table implies 2 additional problems:
The "ID" column is not a Primary Key or dose not have a Unique Index on it; meaning that duplicates were inserted
The column is (likely) no longer an IDENTITY.
Firstly, You'll need to get the new values in there. This can be done with an updatable CTE, with ROW_NUMBER and a windowed MAX
First some sample data:
CREATE TABLE dbo.TestTable (ID int NOT NULL);
INSERT INTO dbo.TestTable (ID)
VALUES(1),(2),(3),(0),(0),(0);
And now to UPDATE the rows with 0:
WITH RNs AS(
SELECT ID,
ROW_NUMBER() OVER (PARTITION BY CASE ID WHEN 0 THEN 0 ELSE 1 END ORDER BY (SELECT NULL)) + --If you have a way of determining the order, change the ORDER BY
MAX(ID) OVER () AS [NewID]
FROM dbo.TestTable)
UPDATE RNs
SET ID = [NewID]
WHERE ID = 0;
Now we (probably) need to fix the table and get the IDENTITY column in there. You can't change a column to an IDENTITY, so we'll need to create a new one and ensure it follows the value of the existing ID.
First, therefore, we need to add a CLUSTERED index to the table, so that the new IDENTITY will use that to generate its value:
ALTER TABLE dbo.TestTable ADD CONSTRAINT PK_TestTable PRIMARY KEY CLUSTERED (ID);
Now we can add the new IDENTITY column:
ALTER TABLE dbo.TestTable ADD IdentityID int IDENTITY NOT NULL;
Then we need to DROP the Primary Key we just created, and then the old column:
ALTER TABLE dbo.TestTable DROP CONSTRAINT PK_TestTable ;
ALTER TABLE dbo.TestTable DROP COLUMN ID;
And then, finally, we can rename the new column, and then recreate the Primary Key:
EXEC sys.sp_rename N'dbo.TestTable.IdentityID','ID','COLUMN';
GO
ALTER TABLE dbo.TestTable ADD CONSTRAINT PK_TestTable PRIMARY KEY CLUSTERED (ID);

How to alter type of a column who is references as Foreign key in other table?

I want to change the dataType of primary key from varchar to bigint.
I tried following command.
ALTER TABLE dbo.Company
ALTER COLUMN Id bigint
but it is not working as this column is referenced as the foreign key in other tables.
How can i change its type without loosing data of the table through Sql Query?
There are several steps to accomplish this. But the main thing, is that first you'll have to drop the key.
First drop the primary (change name_of_primary_key, with yours real):
ALTER TABLE dbo.Company DROP CONSTRAINT name_of_primary_key;
Change the data type (replace length with your desired):
alter table table alter column foreign_key_column bigint(length)
Then drop the foreign key from other tables (make this for every table, and replace the two arguments, with your real from the db):
ALTER TABLE table DROP FOREIGN KEY foreign_key_column;
Now, you change the data type of the foreign key column(replace length with your desired):
alter table table alter column foreign_key_column bigint(length);

SQL Server 8111 - but column is NOT NULLABLE

I want to add a primary key constraint to an existing column on an existing table that contains data. The column is not nullable.
However, when I call
alter table mytable add primary key (mycolumn)
I get an 8111:
Msg 8111, Level 16, State 1, Line 2 Cannot define PRIMARY KEY
constraint on nullable column in table 'mytable'
Even if I call both instructions in a row:
alter table mytable alter column mycolumn INT NOT NULL;
alter table mytable add primary key (mycolumn)
I still get an 8111
- and the column description in SQL Server Management Studio confirms, that mycolumn is set to NOT NULL
What can I do this?
You need to separate your batches. It would be best to include the schema name as well.
alter table dbo.mytable alter column mycolumn INT NOT NULL;
go
alter table dbo.mytable add primary key (mycolumn);
rextester demo: http://rextester.com/TZLEWP56616

How do I set default value for a foreign key column in sql server?

I am adding a new column in an existing table with preloaded data. This column uses a primary key from another table and I want to default this to 5. I have tried the following code:
ALTER TABLE group
ADD group_type INT
GO
ALTER TABLE group
ADD CONSTRAINT FK_group_type DEFAULT 5 FOR group_type
GO
I was expecting on alter of the group table then all the values will be filled with 5 but instead its NULL. What am I doing wrong?
First of all, adding a DEFAULT constraint (in it's own SQL statement) to a column does not effect existing data in that column. It only effects new INSERTS to that table which do not provide a value for that column.
Second, you haven't created a FOREIGN KEY constraint here.
EDIT:
Here would be one way to create the FK correctly
ALTER TABLE group
ADD group_type_id INT
GO
ALTER TABLE group
ADD CONSTRAINT fk_groupType FOREIGN KEY (group_type_id)
REFERENCES group_type (group_type_id)
This worked for me, it set the foreign key constraint, default value, and updated existing table records all in a single ALTER TABLE statement. I'm using a SQL Azure database (via SQL Management Studio), so, YMMV.
ALTER TABLE Group
ADD GroupTypeId int NOT NULL
CONSTRAINT DK_GroupTypeId DEFAULT (5) WITH VALUES
CONSTRAINT FK_GroupTypeId FOREIGN KEY
REFERENCES [dbo].[GroupType] (GroupTypeId)
GO
It took a while to run, but a subsequent select, showed the rows had the correct default value for those columns.
Disclaimer: I edited the above query from my table / key names to yours without re-testing it, so you may want to double check it for any typos or other mismatches; The syntax should be the same though.
You can use:
alter table [group]
add group_type int constraint df_group_type default (5) with values
However, it doesn't seem a good idea to use constant as a default value for a column, which is supposed to be FK column.
It seems, that may be what actually you are trying to do is following:
alter table [group] add column group_type int
GO
update [group] set group_type = (select id from group_type where desc ='typeA')
GO
alter table [group] add constraint FK_group_grouptype foreign key (group_type) references group_type (id)
GO
Adding default constraint will affect existing rows if you add new not nullable column to table.
ALTER TABLE group
ADD group_type INT NOT NULL
CONSTRAINT DK_group_type DEFAULT 5
GO

Primary Key on existing data

I need to delete existing PK from table and create new in new column. Because column for new PK was added later (after table creation) - we have nulls for old rows. Should I use UPDATE statement or there is some option in "ADD CONSTRAINT" clause which automatically determine NULLs and generate GUIDs for them?
Thanks for help.
This is what you have to do.
UPDATE TABLE1
SET GUID = NEWID()
WHERE GUID IS NULL
Now to add a new contstraint, you will have tod elete the old one. This is how you can do it:
ALTER TABLE TABLE1
DROP CONSTRAINT PrimaryKeyName
ALTER TABLE TABLE1
ADD CONSTRAINT PrimaryKeyName PRIMARY KEY (GUID)

Resources