Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Conversione di un campo a Identity

485 views
Skip to first unread message

mario

unread,
Nov 15, 2005, 3:26:49 AM11/15/05
to
Ciao a tutti,
ho ancora bisogno di voi :-)
Questa volta piu' che di un consiglio ho bisogno di una conferma:

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

Andrea Benedetti

unread,
Nov 15, 2005, 3:51:29 AM11/15/05
to
Salve Mario,
"mario" <mar...@ihv.it> ha scritto nel messaggio
news:1132043209....@z14g2000cwz.googlegroups.com...

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


Lorenzo Benaglia

unread,
Nov 15, 2005, 4:19:45 AM11/15/05
to
Andrea Benedetti wrote:
> Non so cosa tu intenda circa "qualche sopresa strana"... ma direi
> proprio che non ne troverai...

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

mario

unread,
Nov 15, 2005, 4:45:35 AM11/15/05
to
Ehmm...
andrebbe bene se son ci fosse un piccolo dettaglio...

> /* 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

Lorenzo Benaglia

unread,
Nov 15, 2005, 4:51:09 AM11/15/05
to

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.

mario

unread,
Nov 15, 2005, 4:59:00 AM11/15/05
to
Scusa Lorenzo, lungi da me dall'aprire una polemica ma Andrea ha
risposto:

"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

Marcello

unread,
Nov 15, 2005, 4:56:31 AM11/15/05
to
Lorenzo Benaglia ha scritto:

> Guarda che la soluzione proposta da Andrea non fa altro che quello che ti ho
> descritto a parole nel post.

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.

Lorenzo Benaglia

unread,
Nov 15, 2005, 5:24:34 AM11/15/05
to
Marcello wrote:
> non fa la stessa cosa...
> Parte da un'"identity insert on" e rimette i medesimi valori che già
> c'erano.

Vero.
Ho lanciato una trace con profiler e leggo:
SET IDENTITY_INSERT dbo.Tmp_Students ON

Ricordavo male.

Ciao!

0 new messages