Ho un database in cui un campo di una tabella e' assolutamente "sacro"
e non si devono perdere i suoi valori.
Questo campo (numero_documento) e' un integer ed e' gia' compilato, e'
la chiave primaria, ci sono circa 600.000 records ognuno col suo
numero_documento che appare anche in altre tabelle per collegarsi a
questa di cui sto parlando.
Ora ho la necessita' di definire questo campo come identity, quindi ho
copiato il db e sulla copia ho provato a modificare la definizione del
campo in identity. Sembra tutto ok, non ha perso i valori originali e
inserendo dati nuovi il numero_documento aumenta normalmente.
Mi posso fidare ad operare la trasformazione sul db ufficiale?
Non e' che fra un mese trovo qualche sorpresa strana?
Devo prendere qualche precauzione?
Grazie :-)
Mario
Il fatto che tu abbia definito il campo come identity istruisce sql server
ad incrementare autonomamente il suo valore sulla base dei precedenti (come
hai potuto notare sul tuo db di sviluppo).
Non ci sono particolari precauzioni da prendere se non quella di fare un
backup ogni volta che si mette in produzione una modifica che cambia la
struttura degli oggetti (o almeno io faccio così).
Non so cosa tu intenda circa "qualche sopresa strana"... ma direi proprio
che non ne troverai...
> Grazie :-)
>
> Mario
Prego, ciao!
--
Andrea
www.absistemi.it - www.ugiss.org
A parte una lentezza nell'operazione dato che Enterprise Manager non farà
altro che definire una nuova tabella con la colonna Identity, copierà le
600.000 righe, eliminerà la tabella originale e rinominerà la nuova tabella.
Questa operazione oltre ad essere lenta richiede uno spazio su disco pari
alle dimensioni della tabella originale.
Il mio consiglio è quello di eseguire da Query Analyzer una serie di ALTER
TABLE per eliminare eventuali constraints sulla colonna in esame,
eliminarla, definirne una nuova con l'attributo IDENTITY e ridefinire
eventuali constraints.
Guarda questo esempio:
USE tempdb
GO
/* Creo la tabella dbo.Students */
CREATE TABLE dbo.Students(
StudentID int NOT NULL,
FirstName varchar(10) NOT NULL,
LastName varchar(10) NOT NULL,
CONSTRAINT PK_Students PRIMARY KEY (StudentID)
)
GO
/* La popolo */
INSERT dbo.Students VALUES(100, 'Lorenzo', 'Benaglia')
INSERT dbo.Students VALUES(110, 'Luca', 'Bianchi')
INSERT dbo.Students VALUES(120, 'Gianluca', 'Hotz')
INSERT dbo.Students VALUES(130, 'Andrea', 'Montanari')
GO
/* Rimuovo il constraint PRIMARY KEY */
ALTER TABLE dbo.Students
DROP CONSTRAINT PK_Students
GO
/* Elimino la colonna StudentID */
ALTER TABLE dbo.Students
DROP COLUMN StudentID
GO
/* Aggiungo la colonna StudentID con l'attributo IDENTITY */
ALTER TABLE dbo.Students
ADD StudentID int NOT NULL IDENTITY
GO
/* Definisco la PRIMARY KEY */
ALTER TABLE dbo.Students
ADD CONSTRAINT PK_Students PRIMARY KEY(StudentID)
GO
/* Vediamo */
SELECT *
FROM dbo.Students
GO
/* Output:
FirstName LastName StudentID
---------- ---------- -----------
Lorenzo Benaglia 1
Luca Bianchi 2
Gianluca Hotz 3
Andrea Montanari 4
(4 row(s) affected)
*/
/* Pulizia */
DROP TABLE dbo.Students
>> Grazie :-)
Prego.
Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
> /* La popolo */
> INSERT dbo.Students VALUES(100, 'Lorenzo', 'Benaglia')
> INSERT dbo.Students VALUES(110, 'Luca', 'Bianchi')
> INSERT dbo.Students VALUES(120, 'Gianluca', 'Hotz')
> INSERT dbo.Students VALUES(130, 'Andrea', 'Montanari')
[cut]
> /* Output:
> FirstName LastName StudentID
> ---------- ---------- -----------
> Lorenzo Benaglia 1
> Luca Bianchi 2
> Gianluca Hotz 3
> Andrea Montanari 4
> (4 row(s) affected)
Io ho bisogno di mantenere i valori dell'ID, se li perdo vengo
malmenato e poi torturato e poi mi fanno tante altre cose poco
simpatiche :-)
In questo caso ha ragione Andrea, ho verificato con i dati precedenti
la trasformazione e sono rimasti tutti uguali.
Grazie :-)
Mario
Guarda che la soluzione proposta da Andrea non fa altro che quello che ti ho
descritto a parole nel post.
Usa il prifiler e te ne renderai conto tu stesso.
La sua soluzione non ti mantiene un bel niente (come la mia del resto),
probabilmente non ci siamo capiti.
In bocca al lupo e buon recovery ;)
> Grazie :-)
Prego.
"Il fatto che tu abbia definito il campo come identity istruisce sql
server
ad incrementare autonomamente il suo valore sulla base dei precedenti
(come
hai potuto notare sul tuo db di sviluppo). "
Sulla base dei precedenti significa che i valori che il campo aveva
prima di diventare identity, li mantiene (se non ho interpretato male).
In effetti concordo con te che il procedimento e' lungo, ho convertito
la tabella modificando il campo a identity e i valori apparentemente li
manteneva.
Essendo pero' un'operazione che non mi era mia capitato di fare volevo
una conferma che sto per intraprendere la via giusta e che non vado
incontro a sgradite sorprese.
Grazie ancora :-)
Mario
Ciao Lorenzo,
non fa la stessa cosa...
Parte da un'"identity insert on" e rimette i medesimi valori che già
c'erano.
> Usa il prifiler e te ne renderai conto tu stesso.
> La sua soluzione non ti mantiene un bel niente (come la mia del resto),
> probabilmente non ci siamo capiti.
...mmm... per me no :-D
> Prego.
marc.
Vero.
Ho lanciato una trace con profiler e leggo:
SET IDENTITY_INSERT dbo.Tmp_Students ON
Ricordavo male.
Ciao!