Temos uma tabela de 5 GB (quase 500 milhões de linhas) e queremos remover a propriedade de identidade em uma das colunas, mas quando tentamos fazer isso através do SSMS, o tempo limite é excedido.
Isso pode ser feito através do T-SQL?
Temos uma tabela de 5 GB (quase 500 milhões de linhas) e queremos remover a propriedade de identidade em uma das colunas, mas quando tentamos fazer isso através do SSMS, o tempo limite é excedido.
Isso pode ser feito através do T-SQL?
Respostas:
Você não pode remover uma IDENTITY
especificação depois de definida.
Para remover a coluna inteira:
ALTER TABLE yourTable
DROP COLUMN yourCOlumn;
Informações sobre ALTER TABLE aqui
Se você precisar manter os dados, mas remover a IDENTITY
coluna, precisará:
IDENTITY
coluna existente para a nova colunaIDENTITY
coluna existente .identity
coluna for usada como parte de uma foreign key
em outra tabela, você terá que eliminar as restrições primeiro e depois agir como o @AdamWenger mencionou sobre a remoção da identidade. attribute/property
Você também pode consultar este link para obter mais detalhes sobre como remover apenas o atributo: blog.sqlauthority.com/2009/05/03/… .. Boa sorte!
Se você quiser fazer isso sem adicionar e preencher uma nova coluna , sem reordenar as colunas e com quase nenhum tempo de inatividade porque nenhum dado está sendo alterado na tabela, vamos fazer alguma mágica com a funcionalidade de particionamento (mas como nenhuma partição é usada, você não não precisa da edição Enterprise):
ALTER TABLE [Original] SWITCH TO [Original2]
exec sys.sp_rename
para renomear os vários objetos de esquema de volta aos nomes originais e, em seguida, você pode recriar suas chaves estrangeiras.Por exemplo, dado:
CREATE TABLE Original
(
Id INT IDENTITY PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value ON Original (Value);
INSERT INTO Original
SELECT 'abcd'
UNION ALL
SELECT 'defg';
Você pode fazer o seguinte:
--create new table with no IDENTITY
CREATE TABLE Original2
(
Id INT PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value2 ON Original2 (Value);
--data before switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;
ALTER TABLE Original SWITCH TO Original2;
--data after switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;
--clean up
IF NOT EXISTS (SELECT * FROM Original) DROP TABLE Original;
EXEC sys.sp_rename 'Original2.IX_Original_Value2', 'IX_Original_Value', 'INDEX';
EXEC sys.sp_rename 'Original2', 'Original', 'OBJECT';
UPDATE Original
SET Id = Id + 1;
SELECT *
FROM Original;
Isso fica confuso com restrições de chave estrangeira e primária, então, aqui estão alguns scripts para ajudá-lo no seu caminho:
Primeiro, crie uma coluna duplicada com um nome temporário:
alter table yourTable add tempId int NOT NULL default -1;
update yourTable set tempId = id;
Em seguida, obtenha o nome da sua restrição de chave primária:
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'yourTable';
Agora tente descartar a restrição de chave primária para sua coluna:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
Se você tiver chaves estrangeiras, ela falhará; portanto, caso contrário, elimine as restrições de chave estrangeira. MANTENHA A TRILHA DE QUADROS QUE VOCÊ EXECUTA ASSIM PARA QUE PODE ADICIONAR AS RESTRIÇÕES MAIS TARDE !!!
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'otherTable';
alter table otherTable drop constraint fk_otherTable_yourTable;
commit;
..
Depois que todas as suas restrições de chave estrangeira forem removidas, você poderá remover a restrição PK, soltar essa coluna, renomear sua coluna temporária e adicionar a restrição PK a essa coluna:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
alter table yourTable drop column id;
EXEC sp_rename 'yourTable.tempId', 'id', 'COLUMN';
ALTER TABLE yourTable ADD CONSTRAINT PK_yourTable_id PRIMARY KEY (id)
commit;
Por fim, adicione as restrições FK novamente em:
alter table otherTable add constraint fk_otherTable_yourTable foreign key (yourTable_id) references yourTable(id);
..
El Fin!
Select t.name 'Table', i.name 'Index', c.name 'Column', i.is_primary_key, i.is_unique From sys.tables t Inner Join sys.indexes i On i.object_id = t.object_id Inner Join sys.index_columns ic ON ic.object_id = i.object_id And i.index_id = ic.index_id Inner Join sys.columns c ON ic.object_id = c.object_id and ic.column_id = c.column_id Where t.name = 'tableName' Order By t.name, i.name, i.index_id, ic.index_column_id
Eu apenas tive esse mesmo problema. 4 instruções no SSMS em vez de usar a GUI e foi muito rápido.
Faça uma nova coluna
alter table users add newusernum int;
Copiar valores acima
update users set newusernum=usernum;
Solte a coluna antiga
alter table users drop column usernum;
Renomeie a nova coluna para o nome da coluna antiga
EXEC sp_RENAME 'users.newusernum' , 'usernum', 'COLUMN';
O script a seguir remove o campo Identidade de uma coluna chamada 'Id'
Espero que ajude.
BEGIN TRAN
BEGIN TRY
EXEC sp_rename '[SomeTable].[Id]', 'OldId';
ALTER TABLE [SomeTable] ADD Id int NULL
EXEC ('UPDATE [SomeTable] SET Id = OldId')
ALTER TABLE [SomeTable] NOCHECK CONSTRAINT ALL
ALTER TABLE [SomeTable] DROP CONSTRAINT [PK_constraintName];
ALTER TABLE [SomeTable] DROP COLUMN OldId
ALTER TABLE [SomeTable] ALTER COLUMN [Id] INTEGER NOT NULL
ALTER TABLE [SomeTable] ADD CONSTRAINT PK_JobInfo PRIMARY KEY (Id)
ALTER TABLE [SomeTable] CHECK CONSTRAINT ALL
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
SELECT ERROR_MESSAGE ()
END CATCH
Abaixo o código está funcionando bem quando não sabemos o nome da coluna de identidade .
Precisa copiar dados para uma nova tabela temporária como Invoice_DELETED
. e da próxima vez que usarmos:
insert into Invoice_DELETED select * from Invoice where ...
SELECT t1.*
INTO Invoice_DELETED
FROM Invoice t1
LEFT JOIN Invoice ON 1 = 0
--WHERE t1.InvoiceID = @InvoiceID
Para obter mais explicações, consulte: https://dba.stackexchange.com/a/138345/101038
ALTER TABLE tablename add newcolumn int
update tablename set newcolumn=existingcolumnname
ALTER TABLE tablename DROP COLUMN existingcolumnname;
EXEC sp_RENAME 'tablename.oldcolumn' , 'newcolumnname', 'COLUMN'
No entanto, o código acima funciona apenas se nenhuma relação de chave estrangeira primária
Apenas para alguém que tem o mesmo problema que eu. Se você quiser apenas inserir algumas vezes, pode fazer algo assim.
Vamos supor que você tenha uma tabela com duas colunas
ID Identity (1,1) | Name Varchar
e deseja inserir uma linha com o ID = 4. Então você aumentou para 3 para que o próximo seja 4
DBCC CHECKIDENT([YourTable], RESEED, 3)
Faça a inserção
INSERT INTO [YourTable]
( Name )
VALUES ( 'Client' )
E retorne sua semente ao ID mais alto, suponha que seja 15
DBCC CHECKIDENT([YourTable], RESEED, 15)
Feito!
Eu tinha o mesmo requisito, e você pode tentar dessa maneira, que eu pessoalmente recomendo, por favor, projete manualmente sua tabela e gere o script, e o que fiz abaixo foi renomear a tabela antiga e também sua restrição para backup.
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.SI_Provider_Profile
DROP CONSTRAINT DF_SI_Provider_Profile_SIdtDateTimeStamp
GO
ALTER TABLE dbo.SI_Provider_Profile
DROP CONSTRAINT DF_SI_Provider_Profile_SIbHotelPreLoaded
GO
CREATE TABLE dbo.Tmp_SI_Provider_Profile
(
SI_lProvider_Profile_ID int NOT NULL,
SI_lSerko_Integrator_Token_ID int NOT NULL,
SI_sSerko_Integrator_Provider varchar(50) NOT NULL,
SI_sSerko_Integrator_Profile varchar(50) NOT NULL,
SI_dtDate_Time_Stamp datetime NOT NULL,
SI_lProvider_ID int NULL,
SI_sDisplay_Name varchar(10) NULL,
SI_lPurchased_From int NULL,
SI_sProvider_UniqueID varchar(255) NULL,
SI_bHotel_Pre_Loaded bit NOT NULL,
SI_sSiteName varchar(255) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile SET (LOCK_ESCALATION = TABLE)
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile ADD CONSTRAINT
DF_SI_Provider_Profile_SIdtDateTimeStamp DEFAULT (getdate()) FOR SI_dtDate_Time_Stamp
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile ADD CONSTRAINT
DF_SI_Provider_Profile_SIbHotelPreLoaded DEFAULT ((0)) FOR SI_bHotel_Pre_Loaded
GO
IF EXISTS(SELECT * FROM dbo.SI_Provider_Profile)
EXEC('INSERT INTO dbo.Tmp_SI_Provider_Profile (SI_lProvider_Profile_ID, SI_lSerko_Integrator_Token_ID, SI_sSerko_Integrator_Provider, SI_sSerko_Integrator_Profile, SI_dtDate_Time_Stamp, SI_lProvider_ID, SI_sDisplay_Name, SI_lPurchased_From, SI_sProvider_UniqueID, SI_bHotel_Pre_Loaded, SI_sSiteName)
SELECT SI_lProvider_Profile_ID, SI_lSerko_Integrator_Token_ID, SI_sSerko_Integrator_Provider, SI_sSerko_Integrator_Profile, SI_dtDate_Time_Stamp, SI_lProvider_ID, SI_sDisplay_Name, SI_lPurchased_From, SI_sProvider_UniqueID, SI_bHotel_Pre_Loaded, SI_sSiteName FROM dbo.SI_Provider_Profile WITH (HOLDLOCK TABLOCKX)')
GO
-- Rename the primary key constraint or unique key In SQL Server constraints such as primary keys or foreign keys are objects in their own right, even though they are dependent upon the "containing" table.
EXEC sp_rename 'dbo.SI_Provider_Profile.PK_SI_Provider_Profile', 'PK_SI_Provider_Profile_Old';
GO
-- backup old table in case of
EXECUTE sp_rename N'dbo.SI_Provider_Profile', N'SI_Provider_Profile_Old', 'OBJECT'
GO
EXECUTE sp_rename N'dbo.Tmp_SI_Provider_Profile', N'SI_Provider_Profile', 'OBJECT'
GO
ALTER TABLE dbo.SI_Provider_Profile ADD CONSTRAINT
PK_SI_Provider_Profile PRIMARY KEY NONCLUSTERED
(
SI_lProvider_Profile_ID
) WITH( PAD_INDEX = OFF, FILLFACTOR = 90, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT TRANSACTION
No SQL Server, você pode ativar e desativar a inserção de identidade da seguinte maneira:
DEFINIR IDENTITY_INSERT table_name ON
- faça suas consultas aqui
DEFINIR IDENTITY_INSERT table_name OFF