How to change the primary key value in sql server? - sql

I am using SQL server 2014.
In my table, I set primary key for the column.The primary key value starts from 1. I want to change it to start from 0. How can I achieve this?

If the table is empty, the easiest thing to do would be to drop the table and recreate it with an identity seed of 0 like GuidoG did. If the table has data, changing the primary key to a 0 (like Intern87 mentions) would be a bad idea because after it inserts a row with a key of 0 the next key would be 1 which would probably already be in the table and therefore would cause further inserts to fail with a primary key duplication error.
So if you have existing data but you MUST have data with a key of 0, I would probably just do an identity insert with row 0. Do this with the following
SET IDENTITY_INSERT mytable ON;
INSERT INTO mytable (id, col1, col2, etc..)
VALUES (0, 'col1data','col2data', etc..);
SET IDENTITY_INSERT mytable OFF;
just make sure to run all of that at once because once you turn identity insert on then other inserts may fail till you turn it off.

this creates a table where the autoinc fields starts with 0 in stead of 1
Also it is best to name your primary key
CREATE TABLE myTable
(
id int IDENTITY(0,1),
othercolumn int,
and so on...
constraint PK_myTableID primary key (id)
)
If however you want to do this with an existing table than your best option is to use Element Zero's anwser

You may be able to reseed it;
DBCC CHECKIDENT ('TableName', RESEED, 0);
GO

Related

Copy a SQL record from a backup and insert into database, keeping the primary key

I need to restore a single row in a table which has been deleted. I have the row in a backup copy of the database. I know that I can copy / paste from one database to another, however (obviously) doing this doesn't keep the primary key value, so it looks like a new record.
How can I insert this row into a table, and keep the original primary key value (which is unique)? There are other tables which reference this keyid, so doing this will prevent us having to make changes elsewhere.
Assuming that this is an IDENTITY Column (which performs an auto-insert of an INT/BIGINT which increments) then you would need to run the SET IDENTITY_INSERT command.
SET IDENTITY_INSERT dbo.MyTable ON;
INSERT INTO dbo.MyTable (Id, Columns) SELECT Id, Columns FROM BackupDb.dbo.MyTable WHERE Id = DeletedRowID
SET IDENTITY_INSERT dbo.MyTable OFF;
Here's the MS Doc related to this command https://learn.microsoft.com/en-us/sql/t-sql/statements/set-identity-insert-transact-sql
Any other type of primary key (such as a Unique Identifier populated by NEWID() should not require IDENTITY_INSERT to be turned on.
Also note that only 1 table can have IDENTITY_INSERT turned on at a time, and the account issuing the command must own or have the ALTER permission on the table.
Let's say your table is set up like this
create table tableWithAutoId (id int identity(1,1) primary key, val varchar(50))
Just doing this (which is basically what you want) will fail
insert into tableWithAutoId(id, val)values(1,'abc')
Cannot insert explicit value for identity column in table 'tableWithAutoId' when IDENTITY_INSERT is set to OFF.
However if you turn on Identity_insert first you can ignore the Identity property on the column
set identity_insert tableWithAutoId ON
insert into tableWithAutoId(id, val)values(1,'abc')
Be sure to turn it back OFF when you're done
set identity_insert tableWithAutoId ON
insert into (column list)
select (column list) from
where = value

MySQL: Increment numerical PK from one point forward

I have a table with a primary key with subsequent values 1,2,3,4,... 1035
I want to insert a new value somewhere in this sequence and increment all values above the said value (actually, the order would be the other way round).
Obviously, I get an error with a simple statement like
UPDATE Table
SET primary_id=primary_id+1
WHERE primary_id > 501
because primary_id 502 is incremented to 503, and 503 already exists.
It seems a very basic question, but I don't remember how to do it.
The table is in MySQL, but I don't think this really matters.
First, take a backup of your table, like this:
CREATE TABLE backup LIKE table;
INSERT INTO backup SELECT * FROM table;
Then, you can run the following queries:
-- remove auto_increment attribute and unique constraint
ALTER TABLE table MODIFY id INT NOT NULL, DROP PRIMARY KEY;
-- your original query
UPDATE table SET id = (id+1) WHERE id > 501;
-- re-add the primary key
ALTER TABLE table MODIFY id INT NOT NULL PRIMARY KEY AUTO_INCREMENT;
If results are OK, remove the backup:
DROP TABLE backup;

Need to drop and recreate SQL table with identity(1:1) on primary key

I have a table with some million records. This table has 1:N relation to some other tables and this other tables have also some 1: N relations. Primary key on this table has auto increment i:1 , this primary key is used in those linked tables so i have to retain these id's
I need to recreate the table with some changes. I can recreate the tables but i need some suggestions on How to retain the auto-generated ID's and populate them so it wont break the relationship with other tables? Or is there any other way for this kind of task ?
Why can't you make changes to the table without re-creating it? Example below add a column to #TableA and then changes its datatype. Alternatively, you can copy the data to a different table and then insert it back to re-created table by enabling identity insert SET IDENTITY_INSERT ON and then inserting identity value.
create table #TableA
(
RecordId int identity(1, 1) primary key not null,
Name nvarchar(128) not null
)
alter table #TableA
add Dob datetime null
alter table #TableA
alter column Dob date null
Example of Identity insert:
SET IDENTITY_INSERT #TableA ON
INSERT INTO #TableA (RecordId, Name, Dob) Values (1, 'some name', '02/04/2014')
SET IDENTITY_INSERT #TableA OFF
You're going to need set identity_insert [on|off]. That will allow inserts and bulk loads of identity columns. After the inserts are done, you'll need to run dbcc checkident with the reseed option to reset the identity counter.
Don't forget to need to drop or disable any related constraints (foreign keys, etc.) and triggers that might cause problems during your remodelling. Or to recreate or reenable them when your done.
After you're all done, you'll probably want to run alter table foo check constraint ... to verify that you haven't broken anything.
Good Luck!
[I recommend a full backup before you start]

How reorder primary key?

I have deleted one row(row 20) in my "table category" ,please let me know that how can i reorder the catid (primary key)? at this time it is 21 after 19.
Thanks
You cannot. The closest you can get is truncate table, which will drop the table and recreate it, which means you lose all data in it, and the ID counter is reset to 0. Other than that, ID will always increment by one from the last inserted record, no matter if that record still exists or not. You can write a query to fix all your current IDs, of course, but upon next insert, it'll still create a new gap. More to the point: if a sequential ordering without gaps is what you want, auto incremental ID is not the proper way to achieve that. Add another int field where you manually keep track of this ordering.
If you care enough about your primary key values that such a value is unwanted, you shouldn't be using auto-number primary keys in the first place.
The whole point with a auto-number key is that you say "As long as the key is unique, I don't really care about its value."
Don't mess with the primary keys. They should never change and you should not use them in your app for anything but joining tables.
Add a new column if you need a gapless index and update this column accordingly when you do inserts/removes. This might sound like useless work for you right now, but it will save you a lot of pain later.
Try this:
UPDATE tbl SET catid = (SELECT COUNT(*) FROM tbl t WHERE t.catid <= tbl.catid);
You might also want to rethink / redesign. Renumbering the entire table when you delete a row doesn't seem likely to be either practical or necessary.
Actually you can.
If your rows have unique enough data and you are using PHPmyAdmin
Delete the Column with the Primary ID
Read the Column with Primary Key and Auto Increment enabled.
What do you mean by reordering primary key? If you are saying that you want the primary key to take 20 instead of 21, then I afraid you can't do that straightaway.
All you can do, is to drop the primary key constraint, then change the 21 to 20, and reapply back the primary key constraint
David is right about not using primary key for indexing and such.
If you'll just have to change a particular primary key value once (I've done it sometimes during migration) you could of course set identity_insert on and copy the row with a insert select and then delete the original one.
For recreating a sort order or an column used as an index in your application you could use the following stored procedure:
CREATE PROCEDURE [dbo].[OrganizeOrderConfirmationMessages]
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sortOrder INT;
SET #sortOrder = 0;
-- // Create temporary table
CREATE TABLE #IDs(ID INT, SortOrder INT)
-- // Insert IDs in order according to current SortOrder
INSERT INTO #IDs SELECT ocm.ID, 0 FROM OrderConfirmationMessages ocm ORDER BY ocm.SortOrder ASC
-- // Update SortOrders
UPDATE #IDs SET SortOrder = #sortOrder, #sortOrder = #sortOrder + 10
-- // Update the "real" values with data from #IDs
UPDATE OrderConfirmationMessages SET SortOrder = x2.SortOrder
FROM #IDs x2 WHERE OrderConfirmationMessages.ID = x2.ID
END
Results:
An example of SortOrders will go from 1,2,5,7,10,24,36 to 10,20,30,40,50,60,70
You should drop the 'catid' field and then create it again, set it as primary and check the Auto Increment checkbox, it will add the new field and fill the numbers.
First drop the primary key column from your table and run this syntax in your phpmyadmin sql section-
ALTER TABLE 'your_tablename' ADD 'column_name' BIGINT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY
('column_name' (10));
This will automatically arrange the column in numbers from 0, 1 and so on.
try this:
SET #var:=0;
UPDATE `table` SET `id`=(#var:=#var+1);
ALTER TABLE `table` AUTO_INCREMENT=1;
In postgres, you can do this where number of records < 300:
update schema.tbl1
set tbl_id = tbl_id + 300;
alter sequence schema.tbl1_id_seq
restart with 1;
insert into schema.tbl1
select nextval('schema.tbl1_id_seq'),
column2,
column3
from schema.tbl1;
delete from schema.tbl1
where tbl1_id > 300;

renumber primary key

How would I reset the primary key counter on a sql table and update each row with a new primary key?
I would add another column to the table first, populate that with the new PK.
Then I'd use update statements to update the new fk fields in all related tables.
Then you can drop the old PK and old fk fields.
EDIT: Yes, as Ian says you will have to drop and then recreate all foreign key constraints.
Not sure which DBMS you're using but if it happens to be SQL Server:
SET IDENTITY_INSERT [MyTable] ON
allows you to update/insert the primary key column. Then when you are done updating the keys (you could use a CURSOR for this if the logic is complicated)
SET IDENTITY_INSERT [MyTable] OFF
Hope that helps!
This may or not be MS SQL specific, but:
TRUNCATE TABLE resets the identity counter, so one way to do this quick and dirty would be to
1) Do a Backup
2) Copy table contents to temp table:
3) Copy temp table contents back to table (which has the identity column):
SELECT Field1, Field2 INTO #MyTable FROM MyTable
TRUNCATE TABLE MyTable
INSERT INTO MyTable
(Field1, Field2)
SELECT Field1, Field2 FROM #MyTable
SELECT * FROM MyTable
-----------------------------------
ID Field1 Field2
1 Value1 Value2
Why would you even bother? The whole point of counter-based "identity" primary keys is that the numbers are arbitrary and meaningless.
you could do it in the following steps:
create copy of yourTable with extra column new_key
populate copyOfYourTable with the affected rows from yourTable along with desired values of new_key
temporarily disable constraints
update all related tables to point to the value of new_key instead of the old_key
delete affected rows from yourTable
SET IDENTITY_INSERT [yourTable] ON
insert affected rows again with the new proper value of the key (from copy table)
SET IDENTITY_INSERT [yourTable] OFF
reseed identity
re-enable constraints
delete the copyOfYourtable
But as others said all that work is not needed.
I tend to look at the identity type primary keys as if they were equivalent of pointers in C, I use them to reference other objects but never modify of access them explicitly
If this is Microsoft's SQL Server, one thing you could do is use the [dbcc checkident](http://msdn.microsoft.com/en-us/library/ms176057(SQL.90).aspx)
Assume you have a single table that you want to move around data within along with renumbering the primary keys. For the example, the name of the table is ErrorCode. It has two fields, ErrorCodeID (which is the primary key) and a Description.
Example Code Using dbcc checkident
-- Reset the primary key counter
dbcc checkident(ErrorCode, reseed, 7000)
-- Move all rows greater than 8000 to the 7000 range
insert into ErrorCode
select Description from ErrorCode where ErrorCodeID >= 8000
-- Delete the old rows
delete ErrorCode where ErrorCodeID >= 8000
-- Reset the primary key counter
dbcc checkident(ErrorCode, reseed, 8000)
With this example, you'll effectively be moving all rows to a different primary key and then resetting so the next insert takes on an 8000 ID.
Hope this helps a bit!