|
Modificare uno User Defined Type
Gli User Defined Type di SQL Server rappresentano un valido strumento per la definizione di
strutture dati a design time, ma purtroppo non possono essere modificati a run time.
Purtroppo, per quanto si possa fare attenzione durante il design di un DB, capita di accorgersi
che il tipo utilizzato per una certa classe di colonne, richiede di essere modificato ad esempio
da int a bigint o da varchar a nvarchar o semplicemente da
nvarchar(64) a nvarchar(128).
Se questa modifica viene fatta a design time, avendo utilizzato gli User Defined Types,
sono sufficienti 10 secondi e non si rischia di commettere errori, mentre con i tipi nativi
le modifiche ed i rischi possono essere considerevoli.
La prima volta che ho utilizzato gli User Defined Types, sono rimasto molto deluso
nello scoprire che una volta creato il DB, non esisteva il modo per eseguire
l' Alter dei tipi.
Che si siano utilizzati i tipi nativi o gli UserType, occorre eseguire degli "ALTER TABLE ALTER COLUMN",
per tutte le colonne passando, comunque, al tipo nativo e a modificare conseguentemente tutte le SP e funzioni.
Benchè a design time gli User Defined Types siano molto utili, con un DB già esistente, non solo
non sono d'aiuto, ma se non si volesse passare al tipo nativo, si dovrebbe creare uno UserType diverso:
es: 1) Creare ETuObjBigPK = bigint
2) Alterare ETuObjectPK --> ETuObjBigPK
Se poi si volesse conservare il primo UserType, sarebbe necessario eseguire 2 volte l'operazione:
es: 1) Creare ETuObjBigPK = bigint
2) Alterare ETuObjectPK --> ETuObjBigPK
3) Modificare ETuObjectPK->bigint
4) Alterare ETuObjBigPK --> ETuObjectPK
Tutto questo, inoltre richiederebbe il Drop e re-Create di SP e funzioni!
Aspettando che MS aggiunga la funzionalità di "ALTER USERTYPE", ho sviluppato una Stored Procedure
(e alcune funzioni ausiliarie) che dovrebbe consentire di eseguire il lavoro in modo automatico.
In base ai miei test, sembra funzionare bene, ma ovviamente non ho potuto provarlo in tutte le possibili situazioni...
La funzione ETfGetIndexColumns ritorna le colonne di un indice.
La funzione ETfGetIndexDef ritorna la definizione di un indice.
La funzione ETfGetEmptyFuncDef ritorna la definizione di una funzione svuotata del codice.
Per poter eseguire gli ALTER delle colonne occorre operare anche su tutti gli oggetti correlatii come
SP, Funzioni, Viste, Checks, FK, PK e bisogna farlo seguendo un ordine preciso;
il tutto viene complicato dal fatto che ad esempio ci possono essere viste dipendenti da una funzione e
funzioni dipendenti da una vista...insomma c'è da divertirsi.
Questa SP, in sintesi, dopo averne salvato la definizione, droppa tutti gli oggetti che dipendono dallo UserType,
lo modifica e ripristina tutti gli oggetti precedentemente droppati.
Per eseguire il lavoro, ho utilizzato una tabella temporanea in cui inserisco tutti gli script che dovranno essere eseguiti,
poi tramite cursori la scorro dal primo all'ultimo record per droppare e in ordine inverso per restorare gli oggetti.
Alcuni oggetti che dichiarano delle variabili di tipo TABLE con campi di tipo "UserType" non possono essere gestiti
sotto transazione perchè provocano una sorta di deadlock; in questo caso occorre eseguire la SP con l'opzione @UnderTran = 0.
Le operazioni che devono essere eseguite dalla SP sono le seguenti:
01) Recuperare il tipo nativo dello UserType
02) Ottenere l'elenco dei campi che necessitano di essere modificati
03) Ottenere l'elenco delle viste ordinate in base alle dipendenze
04) Ottenere l'elenco delle SP ordinate in base alle dipendenze
05) Creare tabella per gli script che si dovranno eseguire
06) Inserire gli script per droppare e ricreare le SP
07) Inserire gli script per droppare e ricreare i Check Constraints
08) Inserire gli script per alterare le Funzioni (svuotare e ripristinare)
09) Inserire gli script per droppare e ricreare le Viste
10) Inserire gli script per droppare e ricreare le Funzioni
11) Inserire gli script per droppare e ricreare le Foreign Key
12) Inserire gli script per droppare e ricreare gli Indici
13) Inserire gli script per droppare e ricreare le Primary Key
14) Inserire gli script per alterare Colonne
15) Inserire gli script per eliminare e ri-creare lo UserType
16) Aprire la transazione (se @UnderTran = 1)
17) Scorrere la tabella degli script per Drop Oggetti
18) Scorrere la tabella degli script per Ripristinare gli Oggetti
19) Chiudere la transazione (se @UnderTran = 1)
20) Droppare le tabelle temporanee
Esempi di Utilizzo:
-- Stampa tutti gli script che sono necessari
-- Le SP lunghe potrebbero non essere complete
EXEC ETpAlterUserDefType N'ETuObjectPK', N'bigint', N'PRINT'
-- Ritorna un dataset con tutti gli script necessari
EXEC ETpAlterUserDefType N'ETuObjectPK', N'bigint', N'SELECT'
-- Esegue l'operazione sotto transazione
-- per consentire il roolback in caso di errore
EXEC ETpAlterUserDefType N'ETuObjectPK', N'bigint', N'EXEC'
-- Esegue l'operazione senza transazione
-- per consentire la modifica delle funzioni "Tabella"
EXEC ETpAlterUserDefType N'ETuObjectPK', N'bigint', N'EXEC', 0
|