Как изменить значения столбца идентификаторов программно?


у меня есть база данных MS SQL 2005 с таблицей Test в графе ID. ID - это столбец идентификаторов.

у меня есть строки в этой таблице, и все они имеют свой соответствующий идентификатор autoincremented значение.

теперь я хотел бы изменить каждый идентификатор в этой таблице следующим образом:

ID = ID + 1

но когда я это делаю, я получаю сообщение об ошибке:

Cannot update identity column 'ID'.

Я попытался это:

ALTER TABLE Test NOCHECK CONSTRAINT ALL 
set identity_insert ID ON

но это не решит проблему.

I нужно установить идентификатор в этот столбец, но мне нужно время от времени менять значения. Поэтому мой вопрос заключается в том, как выполнить эту задачу.

13 155

13 ответов:

вам нужно

set identity_insert YourTable ON

затем удалите строку и вставьте ее с другой идентичностью.

после того, как вы сделали вставку не забудьте выключить identity_insert

set identity_insert YourTable OFF

IDENTITY значения столбцов являются неизменными.

однако можно переключить метаданные таблицы, чтобы удалить IDENTITY свойства, выполните обновление, а затем вернуться.

предполагая следующую структуру

CREATE TABLE Test
(
ID INT IDENTITY(1,1) PRIMARY KEY,
X VARCHAR(10)
)

INSERT INTO Test 
OUTPUT INSERTED.*
SELECT 'Foo' UNION ALL
SELECT 'Bar' UNION ALL
SELECT 'Baz'

затем вы можете сделать

/*Define table with same structure but no IDENTITY*/
CREATE TABLE Temp
(
ID INT PRIMARY KEY,
X VARCHAR(10)
)

/*Switch table metadata to new structure*/
ALTER TABLE Test SWITCH TO Temp;

/*Do the update*/
UPDATE Temp SET ID = ID + 1;

/*Switch table metadata back*/
ALTER TABLE Temp SWITCH TO Test;

/*ID values have been updated*/
SELECT *
FROM Test

/*Safety check in case error in preceding step*/
IF NOT EXISTS(SELECT * FROM Temp)
    DROP TABLE Temp /*Drop obsolete table*/

в SQL Server 2012 можно иметь столбец автоматического увеличения, который также может быть обновлен более прямолинейно с помощью SEQUENCES

CREATE SEQUENCE Seq
    AS INT
    START WITH 1
    INCREMENT BY 1

CREATE TABLE Test2
(
ID INT DEFAULT NEXT VALUE FOR Seq NOT NULL PRIMARY KEY,
X VARCHAR(10)
)

INSERT INTO Test2(X)
SELECT 'Foo' UNION ALL
SELECT 'Bar' UNION ALL
SELECT 'Baz'

UPDATE Test2 SET ID+=1

через пользовательский интерфейс в диспетчере SQL Server 2005 измените столбец удалите свойство autonumber (identity) столбца (выберите таблицу, щелкнув правой кнопкой мыши на ней и выберите "дизайн").

затем запустите запрос:

UPDATE table SET Id = Id + 1

затем перейдите и добавьте свойство autonumber обратно в столбец.

во-первых, установка IDENTITY_INSERT вкл или выкл по этому вопросу не будет работать для того, что вам требуется (он используется для вставки новых значений, таких как затыкание пробелов).

выполнение операции через графический интерфейс просто создает временную таблицу, копирует все данные в новую таблицу без поля идентификатора и переименовывает таблицу.

это можно сделать с помощью временной таблицы.

идея

  • отключить ограничения (в случае, если Ваш идентификатор ссылается на внешний ключ)
  • создать временную таблицу с новым идентификатором
  • удалить содержимое таблицы
  • скопируйте данные из скопированной таблицы в исходную таблицу
  • включить ранее отключенные ограничения

SQL-запросы

Предположим ваш test таблица есть два дополнительных столбца (column2 и column3) и что есть 2 таблицы, имеющие внешние ключи ссылки test под названием foreign_table1 и foreign_table2 (потому что реальные жизненные проблемы никогда не бывают простыми).

alter table test nocheck constraint all;
alter table foreign_table1 nocheck constraint all;
alter table foreign_table2 nocheck constraint all;
set identity_insert test on;

select id + 1 as id, column2, column3 into test_copy from test v;
delete from test;
insert into test(id, column2, column3)
select id, column2, column3 from test_copy

alter table test check constraint all;
alter table foreign_table1 check constraint all;
alter table foreign_table2 check constraint all;
set identity_insert test off;
drop table test_copy;

вот и все.

DBCC CHECKIDENT ('databasename.ДБО.заказы', RESEED, 999) вы можете изменить любой номер столбца идентификаторов с помощью этой команды,а также вы можете начать этот номер поля с каждого номера, который вы хотите.например, в моей команде я прошу начать с 1000 (999+1) надеюсь, что этого будет достаточно...удачи

Если столбец не является PK, вы всегда можете создать новый столбец в таблице с увеличенными числами, отбросить оригинал, а затем изменить новый на старый.

любопытно, почему вам может понадобиться для этого... больше всего мне когда-либо приходилось futz с колонками идентификаторов было заполнять номера,и я просто использовал DBCC CHECKIDENT ( tablename,RESEED, newnextnumber)

удачи!

изменение идентификатора может завершиться неудачей в зависимости от ряда факторов, в основном вращающихся вокруг объектов/отношений, связанных со столбцом идентификатора. Похоже, что дизайн БД - это такая же проблема, как и id, который должен редко меняться (я уверен, что у вас есть свои причины и каскадные изменения). Если вам действительно нужно время от времени менять id, я бы предложил либо создать новый фиктивный столбец id, который не является первичным ключом/автономером, которым вы можете управлять самостоятельно и генерировать из текущих значений. Кроме того, идея Chrisotphers выше была бы моим другим предложением, если у вас возникли проблемы с разрешением вставки идентификатора.

удачи

PS это не сбой, потому что последовательный порядок, в котором он работает, пытается обновить значение в списке до элемента, который уже существует в списке идентификаторов? хватаясь за соломинку, возможно добавить количество строк+1, а затем, если это работает, вычесть количество строк : - S

Если вам нужно иногда менять идентификаторы, вероятно, лучше не использовать столбец идентификаторов. В прошлом мы реализовали поля autonumber вручную, используя таблицу "счетчики", которая отслеживает следующий идентификатор для каждой таблицы. IIRC мы сделали это, потому что столбцы идентификаторов вызывали повреждение базы данных в SQL2000, но возможность изменять идентификаторы иногда была полезна для тестирования.

вы можете вставить новые строки с измененными значениями, А затем удалить старые строки. В следующем примере измените идентификатор на тот же, что и внешний ключ PersonId

SET IDENTITY_INSERT [PersonApiLogin] ON

INSERT INTO [PersonApiLogin](
       [Id]
      ,[PersonId]
      ,[ApiId]
      ,[Hash]
      ,[Password]
      ,[SoftwareKey]
      ,[LoggedIn]
      ,[LastAccess])
SELECT [PersonId]
      ,[PersonId]
      ,[ApiId]
      ,[Hash]
      ,[Password]
      ,[SoftwareKey]
      ,[LoggedIn]
      ,[LastAccess]
FROM [db304].[dbo].[PersonApiLogin]
GO

DELETE FROM [PersonApiLogin]
WHERE [PersonId] <> ID
GO
SET IDENTITY_INSERT [PersonApiLogin] OFF
GO

сначала сохраните все идентификаторы и измените их программно на значения, которые вы не хотите, затем удалите их из базы данных, а затем вставьте их снова, используя что-то подобное:

use [Name.Database]
go
set identity_insert [Test] ON
insert into [dbo].[Test]
           ([Id])
     VALUES
           (2)
set identity_insert [Test] OFF

для массового использования вставки:

use [Name.Database]
go
set identity_insert [Test] ON
BULK INSERT [Test]
FROM 'C:\Users\Oscar\file.csv'
WITH (FIELDTERMINATOR = ';',
      ROWTERMINATOR = '\n',
      KEEPIDENTITY)
set identity_insert [Test] OFF

выборка данных из файла.csv:

2;
3;
4;
5;
6;

если вы не установите identity_insert для выключения вы получите следующее сообщение об ошибке:

не удается вставить явное значение для столбца identity в таблицу 'Test', когда Параметр identity_insert имеет значение ВЫКЛЮЧЕНО.

Я видел хорошую статью, которая помогла мне в последний момент .. Я пытался вставить несколько строк в таблицу, которая имела столбец идентификаторов, но сделала это неправильно и должна была удалить обратно. Как только я удалил строки, Мой столбец идентификаторов был изменен . Я пытался найти способ, чтобы обновить столбец, который был вставлен, но - не повезло. Итак, при поиске в гугле нашли ссылку ..

  1. удалить столбцы, которые были неправильно вставлены
  2. использовать силовую вставку с помощью идентификация вкл / выкл (поясняется ниже)

http://beyondrelational.com/modules/2/blogs/28/posts/10337/sql-server-how-do-i-insert-an-explicit-value-into-an-identity-column-how-do-i-update-the-value-of-an.aspx

очень хороший вопрос, сначала нам нужно on IDENTITY_INSERT для конкретной таблицы, после этого запустите запрос insert (необходимо указать имя столбца).

Примечание: после редактирования столбца идентичности, не забудьте выкл этот параметр identity_insert. Если вы этого не сделали, вы не сможете редактировать столбец идентификаторов для любого другого стол.

SET IDENTITY_INSERT Emp_tb_gb_Menu ON
     INSERT Emp_tb_gb_Menu(MenuID) VALUES (68)
SET IDENTITY_INSERT Emp_tb_gb_Menu OFF

http://allinworld99.blogspot.com/2016/07/how-to-edit-identity-field-in-sql.html