2009-03-31 22 views
17

¿Hay alguna manera fácil de eliminar una identidad de una tabla en SQL Server 2005?Servidor SQL cómo quitar la identidad de una columna

Cuando uso Management Studio, genera una secuencia de comandos que crea una tabla duplicada sin la identidad, copia los datos, descarta la tabla, luego cambia el nombre de la tabla reflejada, etc. Esta secuencia de comandos tiene 5231 líneas porque esta tabla/la columna tiene muchas relaciones FK.

Me sentiría mucho más cómodo al ejecutar una simple modificación/caída. ¿Algunas ideas?

EDITAR
Creo que voy a ir con el guión de 5231 de línea encargado de la empresa. Sin embargo, voy a dividirlo en partes más pequeñas que puedo ejecutar y controlar mejor. En esta tabla se "comporta" extraña, si se intenta eliminar 1 fila (incluso uno que acaba de insertar, que no se encuentra en cualquier otra tabla FK), se obtiene este error:

delete MyTable where MyPrimaryKey=1234 

Msg 8621, Level 17, State 2, Line 1 
    The query processor ran out of stack space during query optimization. Please simplify the query. 

Sin duda, todas las claves ajenas. Detieneremos todos los accesos a nuestra aplicación y correremos en modo de usuario único cuando hagamos estos cambios de esquema y aplicaciones relacionadas. Sin embargo, necesitamos que esto funcione rápido, y necesito una idea de cuánto tiempo tomará. Supongo que tendré que probar, probar y probar.

Respuesta

28

Si está en SQL Server 2005 o posterior, puede hacer esto como un simple cambio de metadatos (NB: no requiere una edición que respalde las particiones como dije originalmente).

Ejemplo de código robado descaradamente de la solución de Paul White en this Microsoft Connect Item.

USE tempdb; 
GO 
-- A table with an identity column 
CREATE TABLE dbo.Source 
(row_id INTEGER IDENTITY PRIMARY KEY NOT NULL, data SQL_VARIANT NULL); 
GO 
-- Some sample data 
INSERT dbo.Source (data) 
VALUES (CONVERT(SQL_VARIANT, 4)), 
     (CONVERT(SQL_VARIANT, 'X')), 
     (CONVERT(SQL_VARIANT, {d '2009-11-07'})), 
     (CONVERT(SQL_VARIANT, N'áéíóú')); 
GO 
-- Remove the identity property 
BEGIN TRY; 
    -- All or nothing 
    BEGIN TRANSACTION; 

    -- A table with the same structure as the one with the identity column, 
    -- but without the identity property 
    CREATE TABLE dbo.Destination 
    (row_id INTEGER PRIMARY KEY NOT NULL, data SQL_VARIANT NULL); 

    -- Metadata switch 
    ALTER TABLE dbo.Source SWITCH TO dbo.Destination; 

    -- Drop the old object, which now contains no data 
    DROP TABLE dbo.Source; 

    -- Rename the new object to make it look like the old one 
    EXECUTE sp_rename N'dbo.Destination', N'Source', 'OBJECT'; 

    -- Success 
    COMMIT TRANSACTION; 
END TRY 
BEGIN CATCH 
    -- Bugger! 
    IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; 
    PRINT ERROR_MESSAGE(); 
END CATCH; 
GO 

-- Test the the identity property has indeed gone 
INSERT dbo.Source (row_id, data) 
VALUES (5, CONVERT(SQL_VARIANT, N'This works!')) 

SELECT row_id, 
     data 
FROM dbo.Source; 
GO 

-- Tidy up 
DROP TABLE dbo.Source; 
+1

¡Esta es una solución increíble! –

+0

¡Guau! ¡Hermosa! –

+1

¡Ha estado buscando esto por años! +99 si pudiera :) – MPritchard

5

Puede agregar una columna a la tabla que no sea una columna de identidad, copiar los datos, soltar la columna original y cambiar el nombre de la nueva columna a la columna anterior y recrear los índices.

Here es un enlace que muestra un ejemplo. Todavía no es un simple alter, pero ciertamente es mejor que 5231 líneas.

+0

esto es casi lo mismo que lo que hace el script 5231 line Management Studio, pero dado que no existe una forma real de "alterar tabla" para hacerlo, parece una buena apuesta. –

7

No creo que pueda eliminar directamente la parte de IDENTIDAD de la columna. Su mejor apuesta es, probablemente, a:

  • añadir otra columna no identidad a la mesa
  • copiar los valores de identidad a esa columna
  • caer la columna original identidad
  • cambiar el nombre de la nueva columna para reemplazar el columna original

Si la columna de identidad es parte de una clave u otra restricción, deberá eliminar esas restricciones y volver a crearlas después de que se completen las operaciones anteriores.

Cuestiones relacionadas