SQL Server 2012 - Setting an Identity column on a Primary Key - sql-server

I am trying to set a primary key column to Identity = Yes, on the database diagram.
I clicked on the column to set, and then pressed F4 to bring the Properties for that column. I usually scroll to Identity and change that to Yes but it is not letting me do that now. I think this is happening because the column is set as a foreign key in other tables?
I do not want to remove the joins, is there anyway I can do that?
Here is some screenshots:
The key to change:
The F4 (Properties); change is disabled:

Here is an example using a table test:
create table test(id int, a int)
insert test values(3,1)
alter table test add id_new int identity(1,1)
go
SET IDENTITY_INSERT test ON
delete from test
output deleted.id, deleted.a, deleted.id into test(id, a, id_new)
SET IDENTITY_INSERT test OFF
go
alter table test drop column id
EXEC sp_rename
#objname= 'test.id_new',
#newname = 'id',
#objtype = 'COLUMN'
declare #maxid int = (select max(id) from test)
DBCC CHECKIDENT(test, RESEED, #maxid);
Your column ID be an identity column
You can test here that everything works:
insert test values(10)
select * from test

Related

Alter sql server table Issue

I already created table in database. Now, I need to add "Identity" Column. Please suggest.
Create Cus(id int Pk,Name varchar2(50),Age int);
insert into Cus(id,Name,Age) values (1,'abc',12);
// here i need to add "Identity"
alter table Cus alter column id Identity(1,1)
You cannot use Alter command to add an identity to the table.
Here, you need to create dummy column and drop existing one.
Create table Cus(id int ,[Name] varchar(50),Age int);
insert into Cus(id,[Name],Age) values (1,'abc',12);
Alter Table Cus Add dummyid int identity(1,1)
Alter Table Cus Drop Column id
Exec sp_rename 'Cus.dummyid ', 'id', 'Column'
No you cannot make any column identity after creating from the query.
You have 2 options, either make it from SQL Management Studio or Create another column and copy with identity .
From Management Studio.
Step 1: Select Table design.
Step 2: Change Column properties.
Step 3: Save
Or
You need to create new column with identity.
Create column with identity `Alter table Tablename add newcol int identity(1,1)
Then copy your data from previous column to this column by setting Identity_Insert ON.
Then drop your previous column.
After that change column name by using sp_rename.
Note: But this will change the ordinal position of your column.
ANOTHER OPTION
Create new table with similar structure just make your column
identity whichever you want to be.
Copy data from your old table to new table.
Drop old table.
Change name of new table with old table.
Edit:
For case of Foreign Key relationship
If they are not so many and feasible, then you may drop the constraint.
ALTER TABLE Yourtable
DROP FOREIGN KEY FK_PersonOrder;
Then follow the above steps and recreate them at the last.
ALTER TABLE Yourtable
ADD FOREIGN KEY (yourid) REFERENCES Persons(PersonID);
Finally i got Solution,
I added new column in 'Cus' table.
alter table Cus add tempCusId int identity;
i removed FK relation in User's Table
and i updated identity values in User Table
update user set id=1 where id= 1;
I Compared Id and TempCusId. After update I removed "Pk" relation in Cus table droped Column "Id",i made "TempCusId" as a "Pk" and identity. Finally User table it self "Id" Column I made FK relation.
And if u have multiple values there than go for a "While" loop
DECLARE #NumberofRowint int=30;
DECLARE #inirow INT=23;
Declare #Grade int ;
WHILE #inirow<= #NumberofRow
BEGIN
DECLARE #ProductID INT=(select Id from [Cus] where id=#inirow)
Set #Grade=(select id from Cus where id=#ProductID)
IF(#Grade= #inirow)
BEGIN
updatetbl_Users set Id=#inirow where id=#ProductID
END
SET #inirow = #inirow + 1;
END;

ALTER COLUMN with INTEGER Datatype, NOT NULL, PRIMARY KEY, auto increment

I have a MySQL QUERY and working fine.
QUERY IS:
ALTER TABLE run
CHANGE RN_RUN_ID RN_RUN_ID INT(11) NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (RN_RUN_ID);
I tried to execute same Query and modified in MSSQL which is throwing error.
MSSQL QUERY IS:
ALTER TABLE run ALTER COLUMN RN_RUN_ID
RN_RUN_ID INT NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (RN_RUN_ID);
ERROR IS:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'AUTO_INCREMENT'.
Can you tell me what I did wrong in this query.
You cant do it directly.
See this post: Adding an identity to an existing column
First answer.
In SQL Server there is no such AUTO_INCREMENT option. Please look at the docs. The equivalent is IDENTITY.
You cannot modify a column directly to become IDENTITY. You need to create a new column on the table, or create a new table and rename it. It has some tricky parts (allowing the insert in the identity column, renaming a column, and some other things). Look this SO answer.
There are also differences on the syntax for adding a PK to a table:
ALTER TABLE run
ADD CONSTRAINT PK PRIMARY KEY (rn_run_id)
If you have acces to SQL Server Management Studio you can get the full script easyly:
add a new diagram to the database
add the table to the diagram (rigth click on the window, and use the contextual menu)
save the diagram (you can delete it later)
right click on the table and choose custom view
right click again on the table, and choose "modify custom view". Add the identity, identity initial value, identity increment, key, etc. required elements to the custom view
modify the column properties in the diagram
go to the "Table designer" menu, and choose the last option "Generate change scripts". You'll get an script which does all the changes for you. For example:
An example of doing this process (by modifying the column id of the table test):
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_test
(
id int NOT NULL IDENTITY (10, 2)
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_test SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_test ON
GO
IF EXISTS(SELECT * FROM dbo.test)
EXEC('INSERT INTO dbo.Tmp_test (id)
SELECT id FROM dbo.test WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_test OFF
GO
DROP TABLE dbo.test
GO
EXECUTE sp_rename N'dbo.Tmp_test', N'test', 'OBJECT'
GO
COMMIT
NOTE: the name of the menu options can be different, i don't have an English SSMS at hand right now
Relevant docs:
IDENTITY
DBCC CHECKIDENT
SET IDENTITY_INSERT
ALTER TABLE

Stored procedure select max value and insert

I am trying to select max: value from a table and insert value into same table.
The code is:
CREATE PROCEDURE [dbo].[InsertLogin]
#LOG_ID INT OUTPUT,
#LOG_NAME VARCHAR(100),
#LOG_EMAIL VARCHAR(100)
AS
INSERT INTO login(LOG_NAME, LOG_EMAIL)
VALUES(#LOG_NAME, #LOG_EMAIL)
SET #LOG_ID = ##IDENTITY
The other values are inserting except LOG_ID its getting null.
My guess is your Log_Id column in your Login table is not setup to be an Identity.
Through T-SQL, you have to drop and readd the column:
alter table login
drop column log_id
alter table login
alter column log_id int not null Identity(1,1)
Alternatively you can do this pretty easily in SSMS. Here's a decent article on the subject:
http://blog.sqlauthority.com/2009/05/03/sql-server-add-or-remove-identity-property-on-column/
I'd also recommend using SCOPE_IDENTITY() over ##Identity

SQL Server, How to set auto increment after creating a table without data loss?

I have a table table1 in SQL server 2008 and it has records in it.
I want the primary key table1_Sno column to be an auto-incrementing column. Can this be done without any data transfer or cloning of table?
I know that I can use ALTER TABLE to add an auto-increment column, but can I simply add the AUTO_INCREMENT option to an existing column that is the primary key?
Changing the IDENTITY property is really a metadata only change. But to update the metadata directly requires starting the instance in single user mode and messing around with some columns in sys.syscolpars and is undocumented/unsupported and not something I would recommend or will give any additional details about.
For people coming across this answer on SQL Server 2012+ by far the easiest way of achieving this result of an auto incrementing column would be to create a SEQUENCE object and set the next value for seq as the column default.
Alternatively, or for previous versions (from 2005 onwards), the workaround posted on this connect item shows a completely supported way of doing this without any need for size of data operations using ALTER TABLE...SWITCH. Also blogged about on MSDN here. Though the code to achieve this is not very simple and there are restrictions - such as the table being changed can't be the target of a foreign key constraint.
Example code.
Set up test table with no identity column.
CREATE TABLE dbo.tblFoo
(
bar INT PRIMARY KEY,
filler CHAR(8000),
filler2 CHAR(49)
)
INSERT INTO dbo.tblFoo (bar)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM master..spt_values v1, master..spt_values v2
Alter it to have an identity column (more or less instant).
BEGIN TRY;
BEGIN TRANSACTION;
/*Using DBCC CHECKIDENT('dbo.tblFoo') is slow so use dynamic SQL to
set the correct seed in the table definition instead*/
DECLARE #TableScript nvarchar(max)
SELECT #TableScript =
'
CREATE TABLE dbo.Destination(
bar INT IDENTITY(' +
CAST(ISNULL(MAX(bar),0)+1 AS VARCHAR) + ',1) PRIMARY KEY,
filler CHAR(8000),
filler2 CHAR(49)
)
ALTER TABLE dbo.tblFoo SWITCH TO dbo.Destination;
'
FROM dbo.tblFoo
WITH (TABLOCKX,HOLDLOCK)
EXEC(#TableScript)
DROP TABLE dbo.tblFoo;
EXECUTE sp_rename N'dbo.Destination', N'tblFoo', 'OBJECT';
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
PRINT ERROR_MESSAGE();
END CATCH;
Test the result.
INSERT INTO dbo.tblFoo (filler,filler2)
OUTPUT inserted.*
VALUES ('foo','bar')
Gives
bar filler filler2
----------- --------- ---------
10001 foo bar
Clean up
DROP TABLE dbo.tblFoo
SQL Server: How to set auto-increment on a table with rows in it:
This strategy physically copies the rows around twice which can take a much longer time if the table you are copying is very large.
You could save out your data, drop and rebuild the table with the auto-increment and primary key, then load the data back in.
I'll walk you through with an example:
Step 1, create table foobar (without primary key or auto-increment):
CREATE TABLE foobar(
id int NOT NULL,
name nchar(100) NOT NULL,
)
Step 2, insert some rows
insert into foobar values(1, 'one');
insert into foobar values(2, 'two');
insert into foobar values(3, 'three');
Step 3, copy out foobar data into a temp table:
select * into temp_foobar from foobar
Step 4, drop table foobar:
drop table foobar;
Step 5, recreate your table with the primary key and auto-increment properties:
CREATE TABLE foobar(
id int primary key IDENTITY(1, 1) NOT NULL,
name nchar(100) NOT NULL,
)
Step 6, insert your data from temp table back into foobar
SET IDENTITY_INSERT temp_foobar ON
INSERT into foobar (id, name) select id, name from temp_foobar;
Step 7, drop your temp table, and check to see if it worked:
drop table temp_foobar;
select * from foobar;
You should get this, and when you inspect the foobar table, the id column is auto-increment of 1 and id is a primary key:
1 one
2 two
3 three
If you want to do this via the designer you can do it by following the instructions here "Save changes is not permitted" when changing an existing column to be nullable
Yes, you can. Go to Tools > Designers > Table and Designers and uncheck "Prevent Saving Changes That Prevent Table Recreation".
No, you can not add an auto increment option to an existing column with data, I think the option which you mentioned is the best.
Have a look here.
If you don't want to add a new column, and you can guarantee that your current int column is unique, you could select all of the data out into a temporary table, drop the table and recreate with the IDENTITY column specified. Then using SET IDENTITY INSERT ON you can insert all of your data in the temporary table into the new table.
Below script can be a good solution.Worked in large data as well.
ALTER DATABASE WMlive SET RECOVERY SIMPLE WITH NO_WAIT
ALTER TABLE WMBOMTABLE DROP CONSTRAINT PK_WMBomTable
ALTER TABLE WMBOMTABLE drop column BOMID
ALTER TABLE WMBOMTABLE ADD BomID int IDENTITY(1, 1) NOT NULL;
ALTER TABLE WMBOMTABLE ADD CONSTRAINT PK_WMBomTable PRIMARY KEY CLUSTERED (BomID);
ALTER DATABASE WMlive SET RECOVERY FULL WITH NO_WAIT

SQL Server add auto increment primary key to existing table

As the title, I have an existing table which is already populated with 150000 records. I have added an Id column (which is currently null).
I'm assuming I can run a query to fill this column with incremental numbers, and then set as primary key and turn on auto increment. Is this the correct way to proceed? And if so, how do I fill the initial numbers?
No - you have to do it the other way around: add it right from the get go as INT IDENTITY - it will be filled with identity values when you do this:
ALTER TABLE dbo.YourTable
ADD ID INT IDENTITY
and then you can make it the primary key:
ALTER TABLE dbo.YourTable
ADD CONSTRAINT PK_YourTable
PRIMARY KEY(ID)
or if you prefer to do all in one step:
ALTER TABLE dbo.YourTable
ADD ID INT IDENTITY
CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED
You can't "turn on" the IDENTITY: it's a table rebuild.
If you don't care about the number order, you'd add the column, NOT NULL, with IDENTITY in one go. 150k rows isn't a lot.
If you need to preserve some number order, then add the numbers accordingly. Then use the SSMS table designer to set the IDENTITY property. This allows you to generate a script which will do the column drop/add/keep numbers/reseed for you.
I had this issue, but couldn't use an identity column (for various reasons).
I settled on this:
DECLARE #id INT
SET #id = 0
UPDATE table SET #id = id = #id + 1
Borrowed from here.
If the column already exists in your table and it is null, you can update the column with this command (replace id, tablename, and tablekey ):
UPDATE x
SET x.<Id> = x.New_Id
FROM (
SELECT <Id>, ROW_NUMBER() OVER (ORDER BY <tablekey>) AS New_Id
FROM <tablename>
) x
When we add and identity column in an existing table it will automatically populate no need to populate it manually.
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1)
update
This answer is a small addition to the highest voted answer and works for SQL Server. The question requested an auto increment primary key, the current answer does add the primary key, but it is not flagged as auto-increment. The script below checks for the columns, existence, and adds it with the autoincrement flag enabled.
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTable' AND COLUMN_NAME = 'PKColumnName')
BEGIN
ALTER TABLE dbo.YourTable
ADD PKColumnName INT IDENTITY(1,1)
CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED
END
GO
by the designer you could set identity (1,1)
right click on tbl => desing => in part left (right click) => properties => in identity columns select #column
Properties
idendtity column
If your table has relationship with other tables using its primary or foriegen key, may be it is impossible to alter your table. so you need to drop and create the table again.
To solve these problems you need to Generate Scripts by right click on the database and in advanced option set type of data to script to scheme and data. after that, using this script with the changing your column to identify and regenerate the table using run its query.
your query will be like here:
USE [Db_YourDbName]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Drop TABLE [dbo].[Tbl_TourTable]
CREATE TABLE [dbo].[Tbl_TourTable](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[Family] [nvarchar](150) NULL)
GO
SET IDENTITY_INSERT [dbo].[Tbl_TourTable] ON
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
SET IDENTITY_INSERT [dbo].[Tbl_TourTable] off
Here is an idea you can try.
Original table - no identity column table1
create a new table - call table2 along with identity column.
copy the data from table1 to table2 - the identity column is populated automatically with auto incremented numbers.
rename the original table - table1 to table3
rename the new table - table2 to table1 (original table)
Now you have the table1 with identity column included and populated for the existing data.
after making sure there is no issue and working properly, drop the table3 when no longer needed.
Create a new Table With Different name and same columns, Primary Key and Foreign Key association and link this in your Insert statement of code.
For E.g : For EMPLOYEE, replace with EMPLOYEES.
CREATE TABLE EMPLOYEES(
EmpId INT NOT NULL IDENTITY(1,1),
F_Name VARCHAR(20) ,
L_Name VARCHAR(20) ,
DOB DATE ,
DOJ DATE ,
PRIMARY KEY (EmpId),
DeptId int FOREIGN KEY REFERENCES DEPARTMENT(DeptId),
DesgId int FOREIGN KEY REFERENCES DESIGNATION(DesgId),
AddId int FOREIGN KEY REFERENCES ADDRESS(AddId)
)
However, you have to either delete the existing EMPLOYEE Table or do some adjustment according to your requirement.
alter table /** paste the tabal's name **/
add id int IDENTITY(1,1)
delete from /** paste the tabal's name **/
where id in
(
select a.id FROM /** paste the tabal's name / as a
LEFT OUTER JOIN (
SELECT MIN(id) as id
FROM / paste the tabal's name /
GROUP BY
/ paste the columns c1,c2 .... **/
) as t1
ON a.id = t1.id
WHERE t1.id IS NULL
)
alter table /** paste the tabal's name **/
DROP COLUMN id
Try This Code Bellow:
DBCC CHECKIDENT ('settings', RESEED, 0)
This works in MariaDB, so I can only hope it does in SQL Server: drop the ID column you've just inserted, then use the following syntax:-
ALTER TABLE table_name ADD id INT PRIMARY KEY AUTO_INCREMENT;
No need for another table. This simply inserts an id column, makes it the primary index, and populates it with sequential values. If SQL Server won't do this, my apologies for wasting your time.
Try something like this (on a test table first):
USE your_database_name
GO
WHILE (SELECT COUNT(*) FROM your_table WHERE your_id_field IS NULL) > 0
BEGIN
SET ROWCOUNT 1
UPDATE your_table SET your_id_field = MAX(your_id_field)+1
END
PRINT 'ALL DONE'
I have not tested this at all, so be careful!
ALTER TABLE table_name ADD COLUMN ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT ;
This could be useful

Resources