Procedura dettagliata: applicare tecniche di refactoring del database

Tramite il refactoring in Visual Studio Premium o Visual Studio Ultimate è possibile ridurre il numero di attività ripetitive e soggette a errori che è necessario eseguire durante la progettazione e l'aggiornamento di uno schema di database. Ad esempio, è possibile utilizzare il refactoring per aggiornare i riferimenti a un oggetto di database se il relativo nome deve essere modificato o se l'oggetto deve essere spostato in uno schema diverso. Se si adotta questo approccio, è possibile aumentare sia la velocità che l'accuratezza delle modifiche di routine apportate alla progettazione del database.

In questa procedura dettagliata viene illustrato un scenario tipico dello sviluppo di un database. Per aggiungere funzionalità a un database esistente, è necessario eseguire l'implementazione iniziale e rivederla quindi con un altro membro del team. Durante la revisione si identificheranno diversi problemi che dovranno essere risolti prima di archiviare le modifiche. Si utilizzeranno quindi varie tecniche di refactoring per modificare lo schema.

In questa procedura dettagliata vengono illustrate le seguenti attività:

  • Importazione dello schema di database

  • Implementazione di una tipica attività di sviluppo del database

  • Correzione di un errore di codifica

  • Completamento dell'attività di sviluppo

  • Risoluzione del feedback relativo alla revisione del codice

Prerequisiti

Per completare questa procedura dettagliata, è necessario quanto elencato di seguito:

  • Visual Studio Premium o Visual Studio Ultimate

  • Accesso in sola lettura a un server database in cui è installato il database AdventureWorks2008.

Importazione dello schema di database

Prima di modificare uno schema in un ambiente team, viene di solito estratto un progetto esistente dal sistema di controllo della versione. Per questa procedura dettagliata verrà creato un progetto di database e verrà importato lo schema dal database di esempio AdventureWorks2008.

Per creare un progetto di database

  1. Scegliere Nuovo dal menu File e quindi fare clic su Progetto.

    Verrà visualizzata la finestra di dialogo Nuovo progetto.

  2. In Modelli installati espandere il nodo Database, quindi fare clic sul nodo SQL Server.

  3. Nell'elenco dei modelli fare clic su Progetto di database di SQL Server 2008.

  4. In Nome digitare RefactorAdventureWorks, quindi scegliere OK.

    Viene creata una soluzione contenente un progetto di database vuoto, denominato RefactorAdventureWorks, come progetto di test (noto anche come sandbox).

    Si importerà quindi lo schema da un'istanza distribuita del database AdventureWorks.

Per importare il database AdventureWorks

  1. In Esplora soluzioni o Visualizzazione schema fare clic su RefactorAdventureWorks.

  2. Scegliere Importa oggetti e impostazioni del database dal menu Progetto.

    Nota

    È inoltre possibile fare clic con il pulsante destro del mouse su RefactorAdventureWorks, quindi scegliere Importa oggetti e impostazioni del database.

    Verrà visualizzata la procedura guidata Importa database.

  3. Nell'elenco Connessione database di origine fare clic sulla connessione corrispondente al database AdventureWorks.

    Nota importanteImportante

    Se non è ancora stata stabilita la connessione al database, è innanzitutto necessario fare clic su Nuova connessione per creare una connessione. Per ulteriori informazioni, vedere Procedura: creare una connessione al database.

  4. Al termine dell'importazione degli oggetti e delle impostazioni, fare clic su Avvia, quindi su Fine.

    Durante l'importazione dello schema, gli elementi di progetto che corrispondono agli oggetti del database vengono visualizzati nel progetto di database in Esplora soluzioni e Visualizzazione schema.

    Nota

    Anche se era stata stabilita una connessione al database per importare lo schema, si viene ora disconnessi per lavorare offline.

    Si eseguirà quindi una tipica attività di sviluppo del database, aggiungendo codice al progetto di database.

Implementazione di una tipica attività di sviluppo del database

Per questa attività è stata richiesta l'implementazione del supporto per tenere traccia della cronologia delle assenze di ogni dipendente. Come parte di questa attività è necessario creare gli oggetti seguenti:

  • Una tabella per tenere traccia della data di inizio e di fine di ogni assenza e il tipo di assenza (vacanza, malattia, dovere civico, festività mobile, permesso non retribuito o permesso per lutto). Più avanti in questa procedura dettagliata si aggiungerà una tabella allo schema Person. Ai dati nella tabella sono applicate le restrizioni seguenti:

    • La durata delle assenze non è mai superiore a cinque giorni. (Le assenze più lunghe sono suddivide in più voci).

    • Le assenze hanno intervalli di date validi.

    • La tabella è correlata alla tabella Employee tramite EmployeeID.

  • Una visualizzazione che mostra la cronologia completa delle assenze di ogni dipendente.

  • Una stored procedure che registra un'assenza e aggiorna le ore di vacanza del dipendente, se il tipo di assenza è vacanza.

Per preparare l'aggiunta di codice

  1. Scegliere Visualizzazione schema database dal menu Visualizza.

  2. In Visualizzazione schema espandere il nodo RefactorAdventureWorks.

  3. Se in Visualizzazione schema l'ordinamento è basato sul tipo di oggetto, sulla barra degli strumenti fare clic su Modifica raggruppamento oggetti.

    Nota

    In Visualizzazione schema l'ordinamento è basato sul tipo di oggetto se sono presenti nodi denominati Tabelle e Visualizzazioni. Se in Visualizzazione schema è presente un nodo denominato Schemi, è possibile continuare con la procedura descritta di seguito.

    A questo punto si aggiungerà la tabella AbsenceHistory al progetto di database.

Per aggiungere la tabella AbsenceHistory

  1. In Visualizzazione schema espandere il nodo Schemi, espandere il sottonodo Person, quindi il sottonodo Tables.

  2. Fare clic con il pulsante destro del mouse sul sottonodo Tables, scegliere Aggiungi, quindi Tabella.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  3. In Nome digitare AbsenceHistory e fare clic su Aggiungi.

    Verrà aperto l'editor Transact-SQL con la definizione della tabella AbsenceHistory.

  4. Nell'editor Transact-SQL sostituire la definizione della tabella esistente con il codice seguente:

    CREATE TABLE [Person].[AbsenceHistory]
    (
    [EmployeeID] INT NOT NULL, 
    [BeginDate] DateTime NOT NULL,
    [EndDate] DateTime NOT NULL,
    [AbsenceType] NCHAR(1) NOT NULL
    );
    
  5. Scegliere Salva Person.AbsenceHistory.table.sql dal menu File.

    A questo punto si aggiungerà un vincolo CHECK alla tabella AbsenceHistory.

Per aggiungere il vincolo CHECK alla tabella

  1. In Visualizzazione schema espandere il nodo AbsenceHistory.

  2. Fare clic con il pulsante destro del mouse sul nodo Vincoli, scegliere Aggiungi, quindi fare clic su Vincolo CHECK.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  3. In Nome digitare CK_AbsenceHistory_ValidDates e fare clic su Aggiungi.

    Verrà aperto l'editor Transact-SQL e verrà visualizzata la definizione del vincolo.

  4. Nell'editor Transact-SQL sostituire la definizione del vincolo esistente con il codice seguente:

    ALTER TABLE [Person].[AbsenceHistory]
    ADD CONSTRAINT [CK_AbsenceHistory_ValidDates] 
    CHECK  (EndDate >= BeginDate AND DateDiff(day, EndDate, BeginDate) <= 5)
    go
    EXECUTE sp_addextendedproperty @name = N'MS_Description', 
    @value = 'Check constraint [EndDate]>= [BeginDate]', 
    @level0type = N'SCHEMA', 
    @level0name = N'Person', 
    @level1type = N'TABLE', 
    @level1name = N'AbsenceHistory', 
    @level2type = N'CONSTRAINT', 
    @level2name = N'CK_AbsenceHistory_ValidDates';
    

    Questo codice definisce un vincolo nella tabella per assicurare che la data di fine sia successiva alla data di inizio e che il delta tra le due date non superi cinque giorni.

  5. Scegliere Salva Person.AbsenceHistory.CK_AbsenceHistory_ValidDates.chkconst.sql dal menu File.

    Aggiungere quindi una chiave esterna alla tabella AbsenceHistory.

Per aggiungere la definizione della chiave esterna

  1. In Visualizzazione schema fare clic con il pulsante destro del mouse sul nodo Chiavi, scegliere Aggiungi e fare clic su Chiave esterna.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  2. In Nome digitare FK_AbsenceHistory_Employee_EmployeeID e scegliere Aggiungi.

    Verrà aperto l'editor Transact-SQL e verrà visualizzata la definizione della chiave esterna.

  3. Nell'editor Transact-SQL sostituire la definizione della chiave esterna esistente con il codice seguente:

    ALTER TABLE [Person].[AbsenceHistory]
    ADD CONSTRAINT [FK_AbsenceHistory_Employee_EmployeeID] 
    FOREIGN KEY ([EmployeeID]) 
    REFERENCES [HumanResources].[Employee] ([BusinessEntityID]) 
    ON DELETE NO ACTION ON UPDATE NO ACTION;
    
    GO
    EXECUTE sp_addextendedproperty @name = N'MS_Description', 
        @value = 'Foreign key constraint referencing Employee.BusinessEntityID.', 
        @level0type = N'SCHEMA', 
        @level0name = N'Person', 
        @level1type = N'TABLE', 
        @level1name = N'AbsenceHistory', 
        @level2type = N'CONSTRAINT', 
        @level2name = N'FK_AbsenceHistory_Employee_EmployeeID';
    

    Questo codice definisce una relazione di chiave esterna tra EmployeeID nella tabella AbsenceHistory e BusinessEntityID nella tabella [HumanResources].[Employee].

  4. Scegliere Salva Person.AbsenceHistory.FK_AbsenceHistory_Employee_EmployeeID.fkey.sql dal menu File.

    A questo punto risulta evidente che la tabella dovrebbe invece essere nello schema HumanResources. Questo errore verrà corretto nella procedura successiva.

Correzione di un errore di codifica

Poiché sono già stati definiti vincoli e chiavi esterne, lo spostamento di una tabella e degli oggetti correlati in un schema diverso richiederebbe in genere molto tempo. È possibile utilizzare il refactoring del database per spostare in modo facile e rapido la tabella e gli oggetti correlati nello schema corretto prima di continuare.

Per spostare la tabella AbsenceHistory nello schema di HumanResources

  1. In Visualizzazione schema fare clic con il pulsante destro del mouse sulla tabella AbsenceHistory, scegliere Refactoring e fare clic su Sposta nello schema.

    Verrà visualizzata la finestra di dialogo Sposta nello schema.

  2. Nell'elenco Nuovo schema fare clic su HumanResources.

  3. Verificare che la casella di controllo Anteprima modifiche sia selezionata e scegliere OK.

    Verrà visualizzata la finestra di dialogo Anteprima modifiche. È possibile rivedere le modifiche prima di applicarle al progetto di database.

  4. Scegliere Applica.

    Le modifiche di refactoring vengono applicate al progetto di database. La tabella AbsenceHistory viene spostata dallo schema Person allo schema HumanResources.

  5. In Visualizzazione schema espandere il nodo dello schema HumanResources, quindi espandere il nodo Tabelle.

    La tabella AbsenceHistory viene visualizzata nello schema corretto.

    Nota

    Quando sono stati spostati gli oggetti nello schema corretto, non sono stati modificati i nomi dei file in cui sono definiti gli oggetti. Se si desidera aggiornare i nomi dei file, è necessario rinominarli in Esplora soluzioni.

    Si completeranno quindi i passaggi restanti dell'attività di sviluppo.

Completamento dell'attività di sviluppo

Dopo aver corretto lo schema per la tabella, è necessario creare gli oggetti seguenti:

  • Una visualizzazione che mostra la cronologia completa delle assenze di ogni dipendente.

  • Una stored procedure che registra un'assenza e aggiorna le ore di vacanza del dipendente, se il tipo di assenza è vacanza.

Per aggiungere la visualizzazione vEmployeeAbsenceHistory

  1. In Visualizzazione schema espandere il nodo Visualizzazioni nello schema HumanResources.

  2. Fare clic con il pulsante destro del mouse sul nodo Visualizzazioni, scegliere Aggiungi e fare clic su Visualizzazione.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  3. In Nome digitare vEmployeeAbsenceHistory e scegliere Aggiungi.

    Verrà aperto l'editor Transact-SQL e verrà visualizzata la definizione della visualizzazione.

  4. Nell'editor Transact-SQL sostituire la definizione della visualizzazione esistente con il codice seguente:

    CREATE VIEW [HumanResources].[vEmployeeAbsenceHistory]
    AS 
    SELECT 
        a.* 
        ,c.[Title] 
        ,c.[FirstName] 
        ,c.[MiddleName] 
        ,c.[LastName] 
        ,c.[Suffix] 
    FROM [HumanResources].[Employee] e
        INNER JOIN [Person].[Person] c 
        ON c.[BusinessEntityID] = e.[BusinessEntityID]
        INNER JOIN [AbsenceHistory] a 
        ON e.[BusinessEntityID] = a.[EmployeeID] 
    ;
    
    GO
    EXECUTE sp_addextendedproperty @name = N'MS_Description', 
    @value = 'Returns employee name and absence history.', 
    @level0type = N'SCHEMA', 
    @level0name = N'HumanResources', 
    @level1type = N'VIEW', 
    @level1name = N'vEmployeeAbsenceHistory';
    

    Questo codice definisce una visualizzazione che restituisce dati da una combinazione delle tabelle Employee, Contact e AbsenceHistory.

  5. Scegliere Salva HumanResources.vEmployeeAbsenceHistory.view.sql dal menu File.

    Si aggiungerà quindi una stored procedure.

Per aggiungere la stored procedure uspRecordAbsence

  1. In Visualizzazione schema espandere i nodi Programmazione e Stored procedure nello schema HumanResources.

  2. Fare clic con il pulsante destro del mouse sul nodo Stored procedure, scegliere Aggiungi e fare clic su Stored procedure.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  3. In Nome digitare uspRecordAbsence e scegliere Aggiungi.

    Verrà aperto l'editor Transact-SQL con la definizione della stored procedure.

  4. Nell'editor Transact-SQL sostituire la definizione della stored procedure esistente con il codice seguente:

    CREATE PROCEDURE [HumanResources].[uspRecordAbsence]
    @EmployeeID INT,
    @AbsenceType NCHAR(1),
    @StartDate DATETIME,
    @EndDate DATETIME
    AS
    BEGIN
    BEGIN TRANSACTION
    INSERT INTO [AbsenceHistory] (EmployeeID, BeginDate, EndDate, AbsenceType)
    VALUES(@EmployeeID, @StartDate, @EndDate, @AbsenceType)
    IF (@AbsenceType = 'V')
    BEGIN
    UPDATE [Employee]
    SET [VacationHours] = [VacationHours] - DateDiff(day, @StartDate, @EndDate)
    WHERE [BusinessEntityID] = @EmployeeID
    END
    COMMIT TRANSACTION
    END;
    

    Questo codice definisce una stored procedure che aggiunge una riga nella tabella AbsenceHistory e aggiorna il campo VacationHours nella tabella Employee se il tipo dell'assenza è "V".

  5. Scegliere Salva dbo.uspRecordAbsence.proc.sq dal menu File.

    Nella procedura seguente si risolveranno i problemi indicati nel feedback ricevuto in una revisione del codice.

Risoluzione del feedback relativo alla revisione del codice

Quando il codice è stato rivisto con un altro membro del team, si è ricevuto feedback su diverse procedure consigliate. È stato chiesto di evitare l'utilizzo di SELECT *, in quanto produce avvisi se si eseguono analisi codice statiche sul codice del database. Inoltre, per i nomi utilizzati nella stored procedure, è stato chiesto di specificare nomi completi. Infine è stato chiesto di rinominare la colonna BeginDate in StartDate nella tabella AbsenceHistory.

Nota

I requisiti e gli standard di codifica variano da un team all'altro. Si consiglia di applicare gli standard di codifica in vigore nell'organizzazione al codice Transact-SQL creato. In questa procedura dettagliata vengono illustrati due problemi. Queste tecniche, inoltre, dovrebbero essere generalmente applicate a tutto il nuovo codice (ad esempio, utilizzare tutti nomi completi), non solo a un singolo oggetto di database.

L'implementazione di questi tipi di modifiche può risultare, anche in questo caso, noiosa e soggetta a errori. È possibile utilizzare il refactoring del database per aggiornare in modo rapido e facile il codice del database, il codice di test e i piani di generazione dati.

Per espandere SELECT * nella definizione della visualizzazione

  1. In Visualizzazione schema fare doppio clic sulla visualizzazione vEmployeeAbsenceHistory.

    Verrà aperto l'editor Transact-SQL e verrà visualizzata la definizione della visualizzazione.

  2. Scegliere Refactoring dal menu Dati e fare clic su Espandi caratteri jolly.

    Verrà visualizzata la finestra di dialogo Anteprima modifiche.

  3. Nell'elenco Espandi caratteri jolly fare clic a.*.

    Nel riquadro Anteprima modifiche vengono mostrati gli aggiornamenti che saranno applicati alla visualizzazione.

  4. Scegliere Applica.

    Le modifiche vengono applicate al progetto di database. Si procederà quindi all'indicazione di nomi completi nella stored procedure definita in precedenti passaggi di questa procedura dettagliata.

Per indicare nomi completi nella stored procedure

  1. In Visualizzazione schema fare doppio clic sulla stored procedure uspRecordAbsence.

    Verrà aperto l'editor Transact-SQL con la definizione della stored procedure.

  2. Scegliere Refactoring dal menu Dati e fare clic su Utilizza nomi completi.

    Verrà visualizzata la finestra di dialogo Anteprima modifiche con tutte le modifiche che saranno effettuate se si applica l'operazione di refactoring al progetto.

  3. Dopo aver rivisto le modifiche, fare clic su Applica.

    Le modifiche vengono applicate al progetto di database.

Per rinominare la colonna BeginDate

  1. In Visualizzazione schema espandere la tabella AbsenceHistory, espandere il nodo Columns e fare clic sulla colonna BeginDate.

  2. Scegliere Effettua refactoring dal menu Dati e quindi Rinomina.

    Verrà visualizzata la finestra di dialogo Rinomina.

    Nota

    È inoltre possibile fare clic con il pulsante destro del mouse su BeginDate in Visualizzazione schema, scegliere Refactoring e fare clic su Rinomina.

  3. In Nuovo nome digitare StartDate.

  4. Selezionare la casella di controllo Anteprima modifiche e scegliere OK.

    Verrà visualizzata la finestra di dialogo Anteprima modifiche con tutte le modifiche che saranno effettuate se si applica l'operazione di ridenominazione al progetto di database.

  5. Scegliere Applica.

    Verranno applicate le modifiche. Il nome della colonna verrà aggiornato e il nuovo nome verrà visualizzato in Visualizzazione schema per ogni oggetto aggiornato. Se si apre la definizione per il vincolo relativo alla data specificato precedentemente in questo argomento, anche il vincolo risulterà aggiornato in modo da fare riferimento al nuovo nome della colonna.

Passaggi successivi

A questo punto si consiglia in genere di rivedere gli aggiornamenti con il membro del team che ha eseguito la revisione del codice, quindi di archiviare le modifiche nel controllo della versione. Il progetto di database, la rappresentazione offline dello schema del database, è stato a questo punto aggiornato. Per aggiornare lo schema distribuito, è necessario distribuire tale progetto di database a un database di destinazione.

Quando si applica un'operazione di refactoring al progetto di database, le informazioni su tale operazione vengono registrate in un file di log del refactoring se è possibile rinominare o spostare l'oggetto tramite sp_rename o ALTER. In questa procedura dettagliata, il file di log è denominato RefactorAdventureWorks.refactorlog. Il file di log del refactoring viene utilizzato al momento della distribuzione per mantenere lo scopo delle modifiche di refactoring. Ad esempio, nel log del refactoring verranno registrate modifiche se si rinomina una colonna. Al momento della distribuzione tali informazioni impediranno che la colonna con il nome obsoleto venga eliminata, insieme agli eventuali dati che contiene, e che venga creata una colonna vuota con un nuovo nome. Se si utilizza il refactoring, non sarà necessario aggiungere istruzioni agli script pre-distribuzione e post-distribuzione per mantenere i dati.

Vedere anche

Attività

Procedura: distribuire le modifiche del refactoring del database

Concetti

Spostamento di un oggetto di database in un altro schema

Specifica completa dei nomi degli oggetti di database

Espandere i caratteri jolly nelle istruzioni SELECT

Analisi del codice di database per migliorare la qualità del codice