2009-03-31 9 views
17

Esiste un modo semplice per rimuovere un'identità da una tabella in SQL Server 2005?SQL Server come eliminare l'identità da una colonna

Quando utilizzo Management Studio, genera uno script che crea una tabella mirror senza identità, copia i dati, elimina la tabella, quindi rinomina la tabella mirror, ecc. Questo script contiene 5231 righe perché questa tabella/la colonna ha molte relazioni FK.

Mi sentirei molto più a mio agio con un semplice alter/drop. Qualche idea?

EDIT
penso che sto solo per andare con lo script 5231 dalla linea di Enterprise Manager. Tuttavia, ho intenzione di suddividerlo in parti più piccole che posso eseguire e controllare meglio. Questa tabella "si comporta in modo" strano, se si tenta di eliminare 1 fila (anche un solo appena inserito, che non è in alcun altra tabella FK), si ottiene questo errore:

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. 

Senza dubbio, tutti i FKS. Interromperà l'accesso alla nostra applicazione ed eseguiremo in modalità utente singolo quando eseguiremo questi schemi e le relative modifiche dell'applicazione. Tuttavia, abbiamo bisogno di questo per correre veloce, e ho bisogno di un'idea di quanto tempo ci vorrà. Immagino che dovrò solo testare, testare, testare.

risposta

28

Se si utilizza SQL Server 2005 o versione successiva, è possibile farlo come una semplice modifica dei metadati (NB: non richiede richiedere un'edizione che supporti il ​​partizionamento come inizialmente indicato).

Esempio di codice rubato senza vergogna dalla soluzione alternativa di Paul White su 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

Questa è una soluzione fantastica! –

+0

Wow! Bellissimo! –

+1

Sei a caccia di questo per secoli! +99 se potessi :) – MPritchard

5

È possibile aggiungere una colonna alla tabella che non è una colonna di identità, copiare i dati, rilasciare la colonna originale e rinominare la nuova colonna nella colonna precedente e ricreare gli indici.

Here è un collegamento che mostra un esempio. Ancora non è un semplice alter, ma è sicuramente meglio di 5231 linee.

+0

questo è quasi lo stesso di quello che fa lo script di gestione di linea 5231, ma poiché non esiste un vero "alter table" per farlo, sembra una buona scommessa. –

7

Non credo che sia possibile rilasciare direttamente la parte IDENTITY della colonna. La cosa migliore è probabilmente quello di:

  • aggiungere un'altra colonna di non-identità al tavolo
  • copiare i valori di identità per quella colonna
  • eliminare la colonna identità originaria
  • rinominare la nuova colonna per sostituire la colonna originale

Se la colonna di identità fa parte di una chiave o di un altro vincolo, sarà necessario eliminare tali vincoli e ricrearli dopo aver completato le operazioni di cui sopra.

Problemi correlati