Alter sql server table Issue - sql-server

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;

Related

SQL UPDATE set and ID with another ID min value

Im trying to update a table I have the same Data but with different ID's so i would like to set the ID of both communs to the lowest ID register for the results.
UPDATE TABLENAME
SET EXAMPLEID = LOWER(EXAMPLEID)
WHERE
TID = TID
AND
KID = KID
AND
STREET = STREET
I'm getting the following error:
Msg 8102, Level 16, State 1, Line 1 Cannot update identity column
'EXAMPLEID'
Identity Column is generally used with Primary Key column. In your case if ExampleID is your primary key and also identity Column, You cannot have same ExampleID on two different rows.
Primary Key Column is unique for every row
On the other hand If your column is not PK but Identity Column, then SQL Server does not allow you to update Identity Key Column Value.
But there is a dirty workaround alternative for this (Not Recommended)
You can't update an identity column. You may insert new records with an explicit value using IDENTITY_INSERT, but SQL Server won't let you do an update.
If you really need to do this, the only option you have is to copy the full table temporarily and recreate your final table again with the updated values. This is strongly NOT recommended:
Create a copy of your table, with all related objects (indexes, constraints, etc.), but with no rows (only schema objects).
CREATE TABLE TABLENAME_Mirror (
ExampleID INT IDENTITY,
TID VARCHAR(100),
KID VARCHAR(100),
STREET VARCHAR(100))
Set IDENTITY_INSERT ON on this new table and insert the records with the updated values.
SET IDENTITY_INSERT TABLENAME_Mirror ON
INSERT INTO TABLENAME_Mirror (
ExampleID,
TID,
KID,
STREET)
SELECT
/*Updated values*/
FROM
--....
SET IDENTITY_INSERT TABLENAME_Mirror OFF
Drop the original table and rename the copied one to the original name:
BEGIN TRANSACTION
IF OBJECT_ID('dbo.TABLENAME') is not null
DROP TABLE dbo.TABLENAME
EXEC sys.sp_rename
'dbo.TABLENAME_Mirror',
'TABLENAME'
COMMIT
You might need to reseed the identity with a proper value once the rows are inserted, if you want to keep the same seed as before.

SQLite: Add column with primary key to existing table whilst persisting data

Within the context of SQLite.
I have an existing table which is currently populated with numerous rows of data.
I am trying to add a new primary key column to this table whilst persisting the original data.
As demonstrated below, I have tried the following
Add a new column to the existing table (Id INTEGER).
Change the name of the existing table.
Create a new table which includes the new primary key (Id INTEGER PRIMARY KEY).
Insert all data from the renamed table into the newly created table.
Drop the renamed table.
The reason I thought this would work is because according to SQlite documentation,
A column declared INTEGER PRIMARY KEY will autoincrement.
However I am receiving the following error.
ErrorCode : 19
Message : constraint failed
UNIQUE constraint failed: Person.Id
Result : Constraint
Here is my code.
--Add a new column to the existing table(Id INT).
ALTER TABLE [Person]
ADD Id INTEGER;
--Change the name of the existing table.
ALTER TABLE [Person] RENAME TO Person_temp;
--Create a new table which includes the new PK.
CREATE TABLE Person(
Id INTEGER PRIMARY KEY,
FirstName nvarchar(100) NULL,
LastName nvarchar(100) NULL
);
--Insert all data from the renamed table into the new table.
INSERT INTO Person SELECT * FROM Person_temp;
--Drop the renamed table.
DROP TABLE Person_temp;
Could anyone be kind enough to shed some light?
Since you do not declare column names in your insert query, the column order depends on the order in witch they where created / added. Try to specify the column names. This is usually a good practice anyway
--Insert all data from the renamed table into the new table.
INSERT INTO Person(Id, FirstName, LastName) SELECT Id, FirstName, LastName FROM Person_temp;
By the way, you probably don't need to add the Id column in the first table :
--Insert all data from the renamed table into the new table.
INSERT INTO Person(FirstName, LastName) SELECT FirstName, LastName FROM Person_temp;
the implicit null value for Id will be replaced by the autoincrement
It sure seems like your Id column does not contain unique value in each row. Since you just added the column, each row will have the same value.
The auto increment is there to help when you insert new rows. (You don't have to select max(id), and insert the new row with id = max+1). It won't auto-populate an existing table of data.
SQLite already has a column that could work for what you want. It's called ROWID. Try using that instead of duplicating it with your Id column.

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

Add primary key column in SQL table

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.

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

Resources