2009-06-26 50 views
328

Necesito cambiar la clave primaria de una tabla a una columna de identidad, y ya hay varias filas en la tabla.Agregar una identidad a una columna existente

Tengo un script para limpiar los ID para asegurar que sean secuenciales comenzando en 1, funciona bien en mi base de datos de prueba.

¿Cuál es el comando SQL para modificar la columna para que tenga una propiedad de identidad?

Respuesta

359

No puede alterar las columnas existentes por identidad.

tiene 2 opciones,

  1. crear una nueva tabla con la identidad & eliminar la tabla existente

  2. Crear una nueva columna con la identidad & caer la columna existente

Enfoque 1. (Nueva tabla) Aquí puede retener el existente g valores de datos en la columna de identidad recién creada.

CREATE TABLE dbo.Tmp_Names 
    (
     Id int NOT NULL 
      IDENTITY(1, 1), 
     Name varchar(50) NULL 
    ) 
ON [PRIMARY] 
go 

SET IDENTITY_INSERT dbo.Tmp_Names ON 
go 

IF EXISTS (SELECT * 
      FROM dbo.Names) 
    INSERT INTO dbo.Tmp_Names (Id, Name) 
      SELECT Id, 
        Name 
      FROM dbo.Names TABLOCKX 
go 

SET IDENTITY_INSERT dbo.Tmp_Names OFF 
go 

DROP TABLE dbo.Names 
go 

Exec sp_rename 'Tmp_Names', 'Names' 

Enfoque 2 (columna del New) No se puede retener los valores de los datos existentes en la columna de identidad de nueva creación, la columna de identidad llevará a cabo la secuencia de números.

Alter Table Names 
Add Id_new Int Identity(1, 1) 
Go 

Alter Table Names Drop Column ID 
Go 

Exec sp_rename 'Names.Id_new', 'ID', 'Column' 

Véase el siguiente mensaje Foro de Microsoft SQL Server para más detalles:

How to alter column to identity(1,1)

+36

Si los datos de la tabla son pequeños, esta opción funciona bien. Si la tabla es grande, prefiero otra opción: use ALTER TABLE ... SWITCH para reemplazar el esquema de la tabla con otra versión con una columna IDENTITY pero con un esquema idéntico. La ventaja del enfoque ALTER TABLE ... SWITCH es que se completa rápidamente (menos de 5 segundos para una tabla de mil millones de filas), ya que no es necesario copiar ni modificar datos de la tabla. Sin embargo, hay advertencias y limitaciones. Ver mi respuesta a continuación para más detalles. –

+5

@Justin Grat: ¡Una alternativa muy interesante y que no había considerado! La razón por la que esto funciona es porque IDENTIDAD es una propiedad de columna y no un tipo de datos, por lo que el método SWITCH valida los esquemas entre las dos tablas (antiguas y nuevas) como identificables independientemente de la diferencia de IDENTIDAD. ¡Gracias por compartir! –

+0

Si no tiene demasiados datos, puede crear "crear la tabla" generando un script desde SSMS. Haga clic con el botón derecho en la tabla> Scrip Table as> Create TABLE to> (new query editor?). Luego suéltelo, y dentro de ese script puede agregar la parte 'IDENTITY (1, 1)' con la columna de la clave principal – goamn

57

No se puede modificar una columna para que sea una columna de IDENTIDAD. Lo que tendrá que hacer es crear una nueva columna que se defina como IDENTIDAD desde el principio, luego descartar la columna anterior y cambiarle el nombre al nuevo.

ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1) 

ALTER TABLE (yourTable) DROP COLUMN OldColumnName 

EXEC sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN' 

Marc

+8

No funciona si esta columna es una restricción –

+0

el parámetro \ @objname es ambiguo o el \ @objtype reclamado (columna) es incorrecto. –

+0

@ JennyO'Reilly: pon eso en una pregunta separada, y ** ¡muéstranos ** el comando completo que estás usando! –

0

No creo que se puede modificar una columna existente para ser una columna de identidad usando tsql. Sin embargo, puede hacerlo a través de la vista de diseño de Enterprise Manager.

De forma alternativa, podría crear una nueva fila como columna de identidad, soltar la columna anterior y luego cambiar el nombre de la columna nueva.

ALTER TABLE FooTable 
ADD BarColumn INT IDENTITY(1, 1) 
       NOT NULL 
       PRIMARY KEY CLUSTERED 
+1

tenga en cuenta que si lo hace a través de SSMS/Enterprise Manager: creará una nueva tabla, copiará datos, eliminará la tabla anterior y cambiará el nombre de la nueva. Eso puede ser bastante caro cuando tiene tablas grandes ... –

2

No hay ninguno, por desgracia; la propiedad IDENTITY pertenece a la tabla en lugar de a la columna.

La manera más fácil es hacerlo en la GUI, pero si esto no es una opción, puede recorrer el largo camino de copiar los datos, soltar la columna, volver a agregarla con la identidad y poner el datos de vuelta.

Ver here para una cuenta de golpe por golpe.

3

Por diseño no existe una forma sencilla de activar o desactivar la función de la identidad de una columna existente. La única forma limpia de hacerlo es crear una nueva columna y convertirla en una columna de identidad o crear una nueva tabla y migrar sus datos.

Si utilizamos SQL Server Management Studio para eliminar el valor de identidad en la columna "id", se crea una nueva tabla temporal, los datos se mueven a la tabla temporal, la tabla anterior se descarta y la nueva tabla renombrado

Use Management Studio para realizar el cambio y luego haga clic con el botón derecho en el diseñador y seleccione "Generar secuencia de comandos de cambio".

Verás que esto es lo que hace el servidor SQL en segundo plano.

3

no puede hacerlo así, debe agregar otra columna, soltar la columna original y renombrar la nueva columna o crear una nueva tabla, copiar los datos y soltar la tabla anterior, y luego renombrar la nueva tabla a la tabla anterior

si utiliza SSMS y establece la propiedad de identidad en ON en el diseñador aquí es lo que SQL Server hace detrás de las escenas. Así que si usted tiene una tabla llamada [usuario] esto es lo que sucede si haces ID de usuario y la identidad

BEGIN TRANSACTION 
SET QUOTED_IDENTIFIER ON 
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
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 

GO 
CREATE TABLE dbo.Tmp_User 
    (
    UserID int NOT NULL IDENTITY (1, 1), 
    LastName varchar(50) NOT NULL, 
    FirstName varchar(50) NOT NULL, 
    MiddleInitial char(1) NULL 

    ) ON [PRIMARY] 
GO 

SET IDENTITY_INSERT dbo.Tmp_User ON 
GO 
IF EXISTS(SELECT * FROM dbo.[User]) 
EXEC('INSERT INTO dbo.Tmp_User (UserID, LastName, FirstName, MiddleInitial) 
    SELECT UserID, LastName, FirstName, MiddleInitialFROM dbo.[User] TABLOCKX') 
GO 
SET IDENTITY_INSERT dbo.Tmp_User OFF 
GO 

GO 
DROP TABLE dbo.[User] 
GO 
EXECUTE sp_rename N'dbo.Tmp_User', N'User', 'OBJECT' 
GO 
ALTER TABLE dbo.[User] ADD CONSTRAINT 
    PK_User PRIMARY KEY CLUSTERED 
    (
    UserID 
    ) ON [PRIMARY] 

GO 
COMMIT 

Habiendo dicho que hay una manera de cortar la tabla de sistema para lograrlo estableciendo el valor de bit a bit, sino que es no compatible y no lo haría

161

En SQL 2005 y posteriores, hay un truco para resolver este problema sin cambiar las páginas de datos de la tabla. Esto es importante para tablas grandes donde tocar cada página de datos puede tomar minutos u horas. El truco también funciona incluso si la columna de identidad es una clave principal, es parte de un índice agrupado o no agrupado u otros errores que pueden hacer saltar la más simple solución de "agregar/quitar/renombrar columna".

Este es el truco: puede usar la declaración ALTER TABLE...SWITCH de SQL Server para cambiar el esquema de una tabla sin cambiar los datos, lo que significa que puede reemplazar una tabla con una IDENTIDAD con un esquema de tabla idéntico, pero sin una columna IDENTITY. El mismo truco funciona para agregar IDENTIDAD a una columna existente.

Normalmente, ALTER TABLE...SWITCH se usa para reemplazar eficientemente una partición completa en una tabla particionada con una nueva partición vacía. Pero también se puede usar en tablas no particionadas.

He utilizado este truco para convertir, en menos de 5 segundos, una columna de una tabla de filas de 2,5 mil millones de IDENTIDAD a una IDENTIDAD (para ejecutar una consulta de varias horas cuyo plan de consulta funcionó mejor para columnas que no sean de IDENTIDAD), y luego restauró la configuración de IDENTIDAD, nuevamente en menos de 5 segundos.

Aquí hay un ejemplo de código de cómo funciona.

CREATE TABLE Test 
(
    id int identity(1,1), 
    somecolumn varchar(10) 
); 

INSERT INTO Test VALUES ('Hello'); 
INSERT INTO Test VALUES ('World'); 

-- copy the table. use same schema, but no identity 
CREATE TABLE Test2 
(
    id int NOT NULL, 
    somecolumn varchar(10) 
); 

ALTER TABLE Test SWITCH TO Test2; 

-- drop the original (now empty) table 
DROP TABLE Test; 

-- rename new table to old table's name 
EXEC sp_rename 'Test2','Test'; 

-- update the identity seed 
DBCC CHECKIDENT('Test'); 

-- see same records 
SELECT * FROM Test; 

Obviamente, esto es más complicado que las soluciones en otras respuestas, pero si la tabla es grande, esto puede ser un verdadero salvavidas. Hay algunas advertencias:

  • tendrá que soltar las teclas antes de hacer el cambio y restaurarlas después.
  • mismo para con las funciones SCHEMABINDING, vistas, etc.
  • índices de la tabla nueva tienen que coincidir exactamente con (mismas columnas, mismo orden, etc.)
  • viejas y nuevas tablas deben estar en el mismo grupo de archivos.
  • solo funciona en SQL Server 2005 o posterior
  • Creía anteriormente que este truco solo funciona en las ediciones Enterprise o Developer de SQL Server (porque las particiones solo son compatibles en las versiones Enterprise y Developer), pero Mason G. Zhwiti en su comentario a continuación dice que también funciona en SQL Standard Edition. Supongo que esto significa que la restricción a Enterprise o Developer no se aplica a ALTER TABLE ... SWITCH.

Hay una buena article on TechNet que detalla los requisitos anteriores.

+1

+1 ¿Conoce el origen de este "truco"? Lo encontré por primera vez en las soluciones para [un elemento de conexión] (https://connect.microsoft.com/SQLServer/feedback/details/252226/allow-enabling-and-disabling-of-a-columns-identity-property) pero veo que tu respuesta es anterior a esto. –

+1

Si mi memoria es correcta, obtuve la idea de este artículo: http://www.sqlservercentral.com/articles/T-SQL/61979/ –

+2

FYI, esto parece funcionar también en la versión estándar de SQL 2008 R2. Tal vez habilitaron esta función al igual que ahora han habilitado la capacidad de activar la compresión de respaldo. –

13

Hay solución fría se describe aquí: SQL SERVER – Add or Remove Identity Property on Column

En resumen editar manualmente su mesa en el Administrador de SQL, cambiar la identidad, no guarde los cambios, simplemente mostrar la secuencia de comandos que se creará para los cambios, copiarlo y úsala más tarde.

Es un gran ahorro de tiempo, ya que (el script) contiene todas las claves externas, índices, etc. relacionados con la tabla que modifica. Escribiendo esto manualmente ... Dios no lo quiera.

+0

esta es la solución que usé - SSMS genera el T-SQL para realizar el cambio ... lo hace por creando una nueva tabla temporal del mismo diseño de esquema, luego copiando todas las filas en ella, eliminando el orig y cambiando el nombre. puede tomar un poco de tiempo para funcionar por completo, pero funcionó perfectamente. – mdelvecchio

+0

No creo que Pinal Dave realmente esté diciendo que necesitas ejecutar el script que generas, solo para mostrar qué hace el cambio a través de la UI por ti ... – Zack

+0

Esta funcionalidad de scripting en SSMS (al cambiar la definición de una tabla) es en realidad la única instalación correcta cuando se documenta una tabla particionada. La 'tarea' de ubicación más apropiada -> 'tabla de scripts' siempre se olvida de escribir la función de partición! –

1

Si el póster original realmente quería establecer una columna existente para que fuera PRIMARY KEY para la tabla y realmente no necesitara la columna para ser una columna IDENTITY (dos cosas diferentes), esto se puede hacer a través de t-SQL con :

ALTER TABLE [YourTableName] 
ADD CONSTRAINT [ColumnToSetAsPrimaryKey] PRIMARY KEY ([ColumnToSetAsPrimaryKey]) 

Nota del paréntesis alrededor del nombre de la columna después de la opción PRIMARY KEY.

Aunque esta publicación es antigua y estoy haciendo una suposición sobre la necesidad de los solicitantes, sentí que esta información adicional podría ser útil para los usuarios que encuentren este hilo ya que creo que la conversación podría llevar a creer que una columna existente no puede configurado para ser una clave principal sin agregarlo como una nueva columna primero que sería incorrecta.

2

Soy un desarrollador de Java que pasó a formar parte de un equipo sin un DBA y otro en el que, como desarrollador, no puedo obtener derechos de DBA. Me encargaron mover un esquema completo entre dos bases de datos, así que sin tener un DBA, tuve que hacerlo y hacerlo ejecutando scripts, no pudiendo usar la GUI en SQL Server 2008 porque no tenía privilegios de administrador.

Todo se movió sin problemas, sin embargo, al ejecutar un procedimiento almacenado en el nuevo schema.table, encontré que perdí el campo de identidad en una tabla. Revisé dos veces el script que creó la tabla y estaba allí, sin embargo, SQL Server no lo obtuvo cuando ejecuté el script. Un DBA me dijo más tarde que había visto este mismo problema antes.

En cualquier caso, para SQL Server 2008, estos son los pasos que tomé para resolver esto y funcionó, así que estoy publicando aquí con la esperanza de que sea de ayuda para alguien. Esto es lo que hice, ya que tenía dependencias FK en otra tabla que hacía esto más difícil:

Utilicé esta consulta para verificar que la identidad realmente faltaba y para ver las dependencias en la tabla.

1.) encontrar estadísticas sobre una mesa:

exec sp_help 'dbo.table_name_old'; 

2.) Crear un duplicado, idéntica nueva tabla, excepto añadir un campo de identidad en el campo PK donde había estado antes.

3.) Deshabilita la identidad para mover datos.

SET IDENTITY_INSERT dbo.table_name ON 

4.) Transfiera los datos.

INSERT INTO dbo.table_name_new 
(
field1, field2, etc... 
) 
SELECT 
field1, field2, etc... 
FROM 
dbo.table_name_old; 

5.) Verifique que los datos estén allí.

SELECT * FROM dbo.table_name_new 

6.) Vuelva a habilitar la identidad.

SET IDENTITY_INSERT ToyRecP.ToyAwards.lkpFile_New OFF 

7.) Este es el mejor guión que he encontrado para conseguir todas las relaciones FK para verificar qué tabla (s) de las referencias de tabla originales como dependencias y me encontré con muchos, por lo que es muy bueno!

SELECT f.name AS ForeignKey, 
    OBJECT_NAME(f.parent_object_id) AS TableName, 
    COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName, 
    OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, 
    COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName 
FROM sys.foreign_keys AS f 
INNER JOIN sys.foreign_key_columns AS fc 
    ON f.OBJECT_ID = fc.constraint_object_id 
    ORDER BY ReferenceTableName; 

8.) Asegúrese de que tiene toda la PK y FK guiones para todas las tablas implicadas, antes de este siguiente paso.

9.) Puede hacer clic derecho sobre cada tecla y la escritura esto utilizando SQL Server 2008

10.) La caída de la FK (s) de la tabla (s dependencia), con esta sintaxis:

ALTER TABLE [dbo].[table_name] DROP CONSTRAINT [Name_of_FK] 

11.) la caída de la tabla original:

DROP TABLE dbo.table_name_old; 

13.) los pasos siguientes se basan en los guiones que ha creado en SQL Server 2008 en el paso 9.

--Agregue el PK a la nueva tabla.

--Añada el FK a la nueva tabla.

--Vuelva a colocar el FK en la tabla de dependencias.

14.) Verifique que todo esté correcto y completo. Usé la GUI para mirar las tablas.

15.) Cambie el nombre de la nueva tabla al nombre original de las tablas.

exec sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]'; 

¡Finalmente, todo funcionó!

0

Básicamente hay cuatro pasos lógicos.

  1. Crear una nueva columna de identidad. Active Insertar identidad para esta nueva columna.

  2. Inserte los datos de la columna fuente (la columna que desea convertir a Identidad) en esta nueva columna.

  3. Desactive la identidad de inserción para la nueva columna.

  4. Coloque su columna de origen & cambie el nombre de la nueva columna por el nombre de la columna de origen.

Puede haber algunas complejidades más, como trabajar en varios servidores, etc.

Consulte el siguiente artículo para conocer los pasos (utilizando ssms & T-sql). Estos pasos están destinados a principiantes con menos control sobre T-SQL.

http://social.technet.microsoft.com/wiki/contents/articles/23816.how-to-convert-int-column-to-identity-in-the-ms-sql-server.aspx

0

genera una secuencia de comandos para todas las tablas con clave principal = bigint que no tienen un conjunto de identidad; esto devolverá una lista de scripts generados con cada tabla;

SET NOCOUNT ON; 

declare @sql table(s varchar(max), id int identity) 

DECLARE @table_name nvarchar(max), 
     @table_schema nvarchar(max); 

DECLARE vendor_cursor CURSOR FOR 
SELECT 
    t.name, s.name 
FROM sys.schemas AS s 
INNER JOIN sys.tables AS t 
    ON s.[schema_id] = t.[schema_id] 
WHERE EXISTS (
    SELECT 
    [c].[name] 
    from sys.columns [c] 
    join sys.types [y] on [y].system_type_id = [c].system_type_id 
    where [c].[object_id] = [t].[object_id] and [y].name = 'bigint' and [c].[column_id] = 1 
) and NOT EXISTS 
(
    SELECT 1 FROM sys.identity_columns 
    WHERE [object_id] = t.[object_id] 
) and exists (
    select 1 from sys.indexes as [i] 
    inner join sys.index_columns as [ic] ON i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id 
    where object_name([ic].[object_id]) = [t].[name] 
) 
OPEN vendor_cursor 

FETCH NEXT FROM vendor_cursor 
INTO @table_name, @table_schema 

WHILE @@FETCH_STATUS = 0 
BEGIN 

DELETE FROM @sql 

declare @pkname varchar(100), 
    @pkcol nvarchar(100) 

SELECT top 1 
     @pkname = i.name, 
     @pkcol = COL_NAME(ic.OBJECT_ID,ic.column_id) 
FROM sys.indexes AS [i] 
INNER JOIN sys.index_columns AS [ic] ON i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id 
WHERE i.is_primary_key = 1 and OBJECT_NAME(ic.OBJECT_ID) = @table_name 

declare @q nvarchar(max) = 'SELECT '[email protected]+' FROM ['[email protected]_schema+'].['[email protected]_name+'] ORDER BY '[email protected]+' DESC' 

DECLARE @ident_seed nvarchar(max) -- Change this to the datatype that you are after 
SET @q = REPLACE(@q, 'SELECT', 'SELECT TOP 1 @output = ') 
EXEC sp_executeSql @q, N'@output bigint OUTPUT', @ident_seed OUTPUT 

insert into @sql(s) values ('BEGIN TRANSACTION') 
insert into @sql(s) values ('BEGIN TRY') 

-- create statement 
insert into @sql(s) values ('create table ['[email protected]_schema+'].[' + @table_name + '_Temp] (') 

-- column list 
insert into @sql(s) 
select 
    ' ['+[c].[name]+'] ' + 
    y.name + 

    (case when [y].[name] like '%varchar' then 
    coalesce('('+(case when ([c].[max_length] < 0 or [c].[max_length] >= 1024) then 'max' else cast([c].max_length as varchar) end)+')','') 
    else '' end) 

    + ' ' + 
    case when [c].name = @pkcol then 'IDENTITY(' +COALESCE(@ident_seed, '1')+',1)' else '' end + ' ' + 
    (case when c.is_nullable = 0 then 'NOT ' else '' end) + 'NULL ' + 
    coalesce('DEFAULT ('+(
     REPLACE(
      REPLACE(
       LTrim(
        RTrim(
         REPLACE(
          REPLACE(
           REPLACE(
            REPLACE(
             LTrim(
              RTrim(
               REPLACE(
                REPLACE(
                 object_definition([c].default_object_id) 
                ,' ','~') 
               ,')',' ') 
              ) 
             ) 
            ,' ','*') 
           ,'~',' ') 
          ,' ','~') 
         ,'(',' ') 
        ) 
       ) 
      ,' ','*') 
     ,'~',' ') 
    ) + 
    case when object_definition([c].default_object_id) like '%get%date%' then '()' else '' end 
    + 
    ')','') + ',' 
from sys.columns c 
JOIN sys.types y ON y.system_type_id = c.system_type_id 
    where OBJECT_NAME(c.[object_id]) = @table_name and [y].name != 'sysname' 
order by [c].column_id 


update @sql set s=left(s,len(s)-1) where [email protected]@identity 

-- closing bracket 
insert into @sql(s) values(')') 

insert into @sql(s) values('SET IDENTITY_INSERT ['[email protected]_schema+'].['[email protected]_name+'_Temp] ON') 

declare @cols nvarchar(max) 
SELECT @cols = STUFF(
    (
     select ',['+c.name+']' 
     from sys.columns c 
     JOIN sys.types y ON y.system_type_id = c.system_type_id 
     where c.[object_id] = OBJECT_ID(@table_name) 
     and [y].name != 'sysname' 
     and [y].name != 'timestamp' 
     order by [c].column_id 
     FOR XML PATH ('') 
    ) 
    , 1, 1, '') 

insert into @sql(s) values('IF EXISTS(SELECT * FROM ['[email protected]_schema+'].['[email protected]_name+'])') 
insert into @sql(s) values('EXEC(''INSERT INTO ['[email protected]_schema+'].['[email protected]_name+'_Temp] ('[email protected]+')') 
insert into @sql(s) values('SELECT '[email protected]+' FROM ['[email protected]_schema+'].['[email protected]_name+']'')') 

insert into @sql(s) values('SET IDENTITY_INSERT ['[email protected]_schema+'].['[email protected]_name+'_Temp] OFF') 


insert into @sql(s) values('DROP TABLE ['[email protected]_schema+'].['[email protected]_name+']') 

insert into @sql(s) values('EXECUTE sp_rename N''['[email protected]_schema+'].['[email protected]_name+'_Temp]'', N'''[email protected]_name+''', ''OBJECT''') 

if (@pkname is not null) begin 
    insert into @sql(s) values('ALTER TABLE ['[email protected]_schema+'].['[email protected]_name+'] ADD CONSTRAINT ['[email protected]+'] PRIMARY KEY CLUSTERED (') 
    insert into @sql(s) 
     select ' ['+COLUMN_NAME+'] ASC,' from information_schema.key_column_usage 
     where constraint_name = @pkname 
     GROUP BY COLUMN_NAME, ordinal_position 
     order by ordinal_position 

    -- remove trailing comma 
    update @sql set s=left(s,len(s)-1) where [email protected]@identity 
    insert into @sql(s) values (' )') 
end 

insert into @sql(s) values ('--Run your Statements') 
insert into @sql(s) values ('COMMIT TRANSACTION') 
insert into @sql(s) values ('END TRY') 
insert into @sql(s) values ('BEGIN CATCH') 
insert into @sql(s) values ('  ROLLBACK TRANSACTION') 
insert into @sql(s) values ('  DECLARE @Msg NVARCHAR(MAX) ') 
insert into @sql(s) values ('  SELECT @Msg=ERROR_MESSAGE() ') 
insert into @sql(s) values ('  RAISERROR(''Error Occured: %s'', 20, 101,@msg) WITH LOG') 
insert into @sql(s) values ('END CATCH') 

declare @fqry nvarchar(max) 

-- result! 
SELECT @fqry = (select char(10) + s from @sql order by id FOR XML PATH ('')) 


SELECT @table_name as [Table_Name], @fqry as [Generated_Query] 
PRINT 'Table: '[email protected]_name 
EXEC sp_executeSql @fqry 

    FETCH NEXT FROM vendor_cursor 
    INTO @table_name, @table_schema 
END 
CLOSE vendor_cursor; 
DEALLOCATE vendor_cursor; 
2

La respuesta aceptada es incorrecto: se puede modificar una columna existente para que sea una identidad , siempre y cuando que no contiene algún valor nulo. Después del cambio, la semilla de identidad comenzará en el máximo (columna) + 1.

Entonces, lo que realmente necesita hacer primero es proporcionar valores para todos los nulos.

3

explicación simple

Renombrar la columna existente usando sp_rename

'Table_Name.Existing_ColumnName'

EXEC sp_rename, 'New_ColumnName', 'COLUMNA'

Ejemplo para Cambiar nombre:

La columna existente UserID se renombra como OldUserID

EXEC sp_RENAME 'AdminUsers.UserID' , 'OldUserID', 'COLUMN' 

continuación, agregar una nueva columna usando consulta alter para establecer clave como primario y valor de identidad

ALTER TABLE TableName ADD Old_ColumnName INT NOT NULL PRIMARY KEY IDENTITY(1,1) 

Ejemplo para Programar primario

El nuevo nombre de la columna creada clave es UserID

ALTER TABLE Users ADD UserID INT NOT NULL PRIMARY KEY IDENTITY(1,1) 

luego, suelte la columna renombrada

ALTER TABLE Table_Name DROP COLUMN Renamed_ColumnName 

Ejemplo de gota a llamarse columna

ALTER TABLE Users DROP COLUMN OldUserID 

Ahora hemos de añadir un PrimaryKey e identidad a la columna existente en la tabla.

1

IN sql server 2014 (no sé sobre las versiones más bajas) puede hacer esto simplemente, usando la secuencia.

CREATE SEQUENCE sequence_name START WITH here_higher_number_than_max_existed_value_in_column INCREMENT BY 1; 

ALTER TABLE table_name ADD CONSTRAINT constraint_name DEFAULT NEXT VALUE FOR sequence_name FOR column_name 

A partir de aquí: Sequence as default value for a column

2

Según entendí en casos normales que estamos creando una tabla con clave primaria que está teniendo la propiedad Identidad
Así Cambiar nombre de o Eliminar una columna que está asociado con Clave principalrestricción no será posible causa restricción Las reglas validan estructura de columna.
Tto lograr esto tenemos que procesar algunos pasos de la siguiente manera:
Vamos a suponer NombreTabla = 'Empleado' y ColumnName = 'EmployeeId'

1. Añadir nueva columna 'EmployeeId_new' en el 'empleado' mesa
ALTER tabla de empleados AÑADIR EmployeeId_new INT IDENTIDAD (1,1)

  1. Ahora quitar la columna 'Emp loyeeId' de 'tabla de empleados'
    ALTER TABLE DROP Empleado COLUMNA employeeid

  2. Esto lanzará el error debido a las reglas de restricción de clave principal son aplicables y validar la estructura de la columna.
    * ### 'Msg 5074, nivel 16, estado 1, línea 1 El objeto [PK_dbo.Employee] depende de colmn [EmployeeId].' ###

  3. así que tenemos que quitar la restricción de clave principal en primer lugar de la tabla 'Empleados', entonces podemos eliminar la columna
    ALTER TABLE DROP Empleado restricción [PK_dbo.Employee]

  4. Ahora podemos quitar la columna 'EmployeeId' de la tabla 'Empleados' al igual que en el paso anterior en el que ha obtenido un error
    ALTER TABLE DROP Empleado cOLUMNA employeeid

  5. Ahora Columna 'employeeid' retirado de la mesa Así que vamos a cambiar el nombre de la recién añadida nueva columna 'EmployeeId_new' con 'EmployeeId'
    sp_rename 'Employee.EmployeeId', 'EmployeeId_new', 'COLUMNA'

  6. para ordenar la tabla en la misma forma como lo fue, tenemos que añadir clave principal restricción para la columna 'EmployeeId'
    ALTER TABLE Empleado añadir restricción [PK_dbo.Empleado] clave primaria (EmployeeId)

8. Ahora la tabla 'empleado' con 'EmployeeId' es modificado por las reglas de identidad junto con la restricción de clave primaria existente

0

Según mi actual condición, sigo este enfoque. Quiero dar identidad a una tabla primaria después de los datos insertados a través del script.

Como quiero agregar identidad, por lo que siempre comienza desde 1 hasta el conteo de fin de registro que quiero.

--first drop column and add with identity 
ALTER TABLE dbo.tblProductPriceList drop column ID 
ALTER TABLE dbo.tblProductPriceList add ID INT IDENTITY(1,1) 

--then add primary key to that column (exist option you can ignore) 
IF NOT EXISTS (SELECT * FROM sys.key_constraints WHERE object_id = OBJECT_ID(N'[dbo].[PK_tblProductPriceList]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblProductPriceList]')) 
    ALTER TABLE [tblProductPriceList] ADD PRIMARY KEY (id) 
GO 

Esto creará la misma columna de clave principal con la identidad

utilicé esta enlaces: https://blog.sqlauthority.com/2014/10/11/sql-server-add-auto-incremental-identity-column-to-table-after-creating-table/

Add primary key to existing table

1

Haga clic derecho sobre el nombre de tabla en el Explorador de objetos. Obtendrás algunas opciones. Haga clic en 'Diseño'. Se abrirá una nueva pestaña para esta tabla. Puede agregar una restricción de Identidad aquí en 'Propiedades de columna'.

1

Para modificar las propiedades de identidad de una columna:

  • En el Explorador de servidores, haga clic en la tabla con propiedades de identidad que desea modificar y haga clic en Abrir tabla de definición. La tabla se abre en Table Designer.
  • Desactive la casilla de verificación Permitir nulos para la columna que desea cambiar.
  • En la pestaña Propiedades de columna, expanda la propiedad Especificación de identidad.
  • Haga clic en la celda de la cuadrícula para la propiedad hija Is Identity y elija Sí en la lista desplegable.
  • Escriba un valor en la celda de la semilla de identidad. Este valor se asignará a la primera fila de la tabla. El valor 1 se asignará por defecto.

Eso es todo, y funcionó para mí

Cuestiones relacionadas