SQL UPDATE set and ID with another ID min value - sql-server

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.

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;

SQL Server creating a Table with an IDENTITY COLUMN - uniqueness

In SQL Server, I have created a Table with an ID column that I have made an IDENTITY COLUMN,
EmployeeID int NOT NULL IDENTITY(100,10) PRIMARY KEY
It is my understanding, when I use the IDENTITY feature, it auto increments the EmployeeID. What I don't know/not sure is:
Is that IDENTITY number created, unique?
Does SQL search the entire column in the table to confirm the number created does not already exist?
Can I override that auto increment number manually?
If I did manually override that number, would the number I enter be checked to make sure it is not a duplicate/existing ID number?
Thanks for any help provided.
Is that IDENTITY number created, unique?
Yes, Identity property is unique
Does SQL search the entire column in the table to confirm the number created does not already exist? \
It need not, what this property does is, just incrementing the old value
Can I override that auto increment number manually?
Yes, you can. You have to use SET IDENTITY_INSERT TABLENAME ON
If I did manually override that number, would the number I enter be checked to make sure it is not a duplicate/existing ID number?
No, that won't be taken care by SQL Server, you will have to ensure you have constraints to take care of this
Below is a simple demo to prove that
create table #temp
(
id int identity(1,1)
)
insert into #temp
default values
go 3
select * from #temp--now id column has 3
set identity_insert #temp on
insert into #temp (id)
values(4)
set identity_insert #temp off
select * from #temp--now id column has 4
insert into #temp
default values
go
select * from #temp--now id column has 5,next value from the last highest
Updating info from comments:
Identity column will allow gaps once you reseed them,also you can't update them

Alter column to be identity

I've already read the following answers about the impossibility to alter a column into identity once has been created as a regular int.
Adding an identity to an existing column
How to Alter a table for Identity Specification is identity SQL Server
How to alter column to identity(1,1)
But the thing is I have a table which has been migrated to a new one where the ID was not declared as identity from the beginning, because the old table which was created with an ID identity a long time ago has missing rows due to a purge of historical data. So as far as I know, if I add a new column as identity on my new table, it will automatically create the column sequentially and I need to preserve the IDs from the old table as-is because there is already data linked to these previous IDs.
How can I do transform my ID column from the new table as identity but not sequentially, but with the IDs from the old table?
You could try this approach:
Insert rows with old ID with SET IDENTITY_INSERT <new table> ON. This allows you to insert your own ID.
Reseed the Identity, setting it to the highest ID value +1 with DBCC CHECKIDENT ('<new table>', RESEED, <max ID + 1>). This will allow your Identity to increase from the highest ID and forward.
Something like this in code:
-- Disable auto increment
SET IDENTITY_INSERT <new table> ON
-- <INSERT STUFF HERE>
SET IDENTITY_INSERT <new table> OFF
-- Reseed Identity from max ID
DECLARE #maxval Int
SET #maxval = ISNULL(
(
SELECT
MAX(<identity column>) + 1
FROM <new table>
), 0)
DBCC CHECKIDENT ('<new table>', RESEED, #maxval)
EDIT: This approach requires your ID-column to be an Identity, of course.
If you don't have nulls in the field that you want to copy over from your previous version, you could first figure out what the largest ID is by just doing a max(Id) select. Then using SSMS go add your new field and when you set it as identity, just set the SEED value to something higher than what your current max is so you don't have collisions on new inserts.
I have a process where a temp table is used between a source file, CSV and the production table. The temp table has to match the CSV file columns, there is no PK in this data.
To find a set of rows before and after where the Azure Data Factory was failing, I imported over 2,000,000 rows into a temp table. The process stopped in Azure at 1,500,000 rows.
The error was that an integer or string would be truncated.
This line of code added a PK to the temp table and incremented it:
ALTER TABLE ##FLATFILETEMPBDI ADD ROWNUM INT IDENTITY
That would be the simplest solution to get a row number. I was then able to do this query to find the rows just before and after 1,500,000:
SELECT
ROWNUM
, PARTDESCRIPTION
, LEN(PARTDESCRIPTION) AS LENDESCR
, QUANTITY
, ONORDER
, PRICE
, MANUFACTURERPARTNUMBER
FROM ##FLATFILETEMPBDI
WHERE ROWNUM BETWEEN 1499990 AND 1500005
Works perfectly -- was not planning on it to be that easy, was surprised as anyone to see that the ALTER TABLE with IDENTITY worked to do the numbering for me.

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.

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