Как изменить значения столбца идентификаторов программно?
у меня есть база данных 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 ответов:
вам нужно
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 имеет значение ВЫКЛЮЧЕНО.
Я видел хорошую статью, которая помогла мне в последний момент .. Я пытался вставить несколько строк в таблицу, которая имела столбец идентификаторов, но сделала это неправильно и должна была удалить обратно. Как только я удалил строки, Мой столбец идентификаторов был изменен . Я пытался найти способ, чтобы обновить столбец, который был вставлен, но - не повезло. Итак, при поиске в гугле нашли ссылку ..
- удалить столбцы, которые были неправильно вставлены
- использовать силовую вставку с помощью идентификация вкл / выкл (поясняется ниже)
очень хороший вопрос, сначала нам нужно 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