Compartir a través de


Tutorial: Modificar proyectos de base de datos utilizando el modelo de automatización de Visual Studio

Actualización: noviembre 2007

Puede modificar mediante programación sus proyectos de base de datos utilizando la compatibilidad de la extensibilidad en Visual Studio. Los proyectos de base de datos en Visual Studio Team System Database admiten el modelo de automatización de Visual Studio (también conocido como extensibilidad en tiempo de diseño o DTE) de una manera que es coherente con Visual C# y los proyectos de Visual Basic. Para obtener más información sobre este modelo, vea Ampliar el entorno de Visual Studio. En este tutorial, va a crear macros de Visual Studio que utilizan el modelo de automatización para lograr dos tareas:

  • Alternar la acción de generar de todos los desencadenadores en un proyecto de base de datos. Si los desencadenadores están establecidos en "Compilación", la macro los cambia a "No está en la compilación". Si los desencadenadores están establecidos en "No está en la compilación", la macro los cambia a "Compilación".

  • Agregue todos los archivos de script de un directorio a una carpeta de un proyecto de base de datos. Si la carpeta no existe, se crea. Sólo se agregan archivos de script que tienen extensiones concretas.

También podría realizar estas tareas en un complemento de Visual Studio escrito en Visual C# o en Visual Basic. Para simplificar, este tutorial utiliza macros.

En los procedimientos siguientes, va a:

  • Crear un proyecto de base de datos organizado por tipo de objeto e importar el esquema de base de datos de AdventureWorks.

  • Iniciar el Explorador de macros y crear los módulos para contener las macros y el código compatible.

  • Crear una macro que alterne la acción de generar para todos los desencadenadores de un proyecto de base de datos en la solución abierta.

  • Crear una macro y el código de compatibilidad para agregar los scripts al proyecto de base de datos.

  • Ejecutar la macro ToggleTriggers desde la Ventana de comandos.

  • Ejecutar la macro AddScriptsInDirectory desde el Explorador de macros.

Requisitos previos

Para completar este tutorial, debe haber instalado Database Edition. En este tutorial se supone que tiene instalada una copia de la base de datos de ejemplo AdventureWorks en un servidor de base de datos que ejecuta Microsoft SQL Server 2005. Puede sustituir cualquier otro proyecto de base de datos que esté organizado por tipo de objeto. Debe haber uno o más archivos con la extensión .sql en un directorio al que tenga acceso.

Para crear un proyecto de base de datos

  1. Inicie Visual Studio si aún no lo ha hecho.

  2. En el menú Archivo, seleccione Nuevo y, a continuación, haga clic en Proyecto.

    Aparecerá el cuadro de diálogo Nuevo proyecto.

  3. En la lista Tipos de proyecto, expanda el nodo Proyectos de base de datos y haga clic en Microsoft SQL Server.

  4. En la lista Plantillas, haga clic en SQL Server 2005.

  5. En Nombre, escriba MyAdvWorks y acepte los valores predeterminados para Ubicación y Nombre de la solución.

  6. Active la casilla Crear directorio para la solución si no está activada de manera predeterminada y haga clic en Aceptar.

    Se crea una solución que contiene el proyecto de base de datos MyAdvWorks, que está vacío.

    A continuación, iniciará el proceso de importación del esquema de base de datos, en el que debe especificar una cadena de conexión a la base de datos de origen.

Para importar el esquema de la base de datos AdventureWorks existente

  1. En el menú Ver, haga clic en Vista de esquema.

    Si no estaba visible, aparece la Vista de esquema.

  2. Haga clic en MyAdvWorks en Vista de esquema.

  3. En el menú Proyecto, haga clic en Importar esquema de base de datos.

    Nota:

    También puede hacer clic con el botón secundario del mouse en MyAdvWorks y, después, hacer clic en Importar esquema de base de datos.

    Aparecerá el Asistente para importar bases de datos.

  4. En la lista Conexión debase de datos de origen, haga clic en la conexión que corresponde a la base de datos AdventureWorks existente. Si no se ha conectado aún a la base de datos, debe crear primero una conexión. Para obtener más información, vea Cómo: Crear una conexión de base de datos.

  5. Haga clic en Finalizar.

    Cuando se importa el esquema, los elementos de proyecto que se corresponden con los objetos de la base de datos se muestran bajo el proyecto de base de datos en el Explorador de soluciones. La Vista de esquema muestra los objetos definidos en el proyecto de base de datos.

Para iniciar el Explorador de macros y crear módulos

  1. En el menú Ver, elija Otras ventanas y, a continuación, haga clic en Explorador de macros.

    Aparece el Explorador de macros.

  2. En el Explorador de macros, haga clic con el botón secundario del mouse en el nodo MyMacros y haga clic en Nuevo módulo.

    Aparecerá el cuadro de diálogo Agregar módulo.

  3. En Nombre, escriba BuildActionExample.

  4. Haga clic en Agregar.

  5. En el Explorador de macros, haga clic con el botón secundario del mouse en el nodo MyMacros y haga clic en Nuevo módulo.

    Aparecerá el cuadro de diálogo Agregar módulo.

  6. En Nombre, escriba ImportScriptsExample.

  7. Haga clic en Agregar.

    A continuación va a crear una macro para alternar la acción de generar de todos los desencadenadores de Lenguaje de manipulación de datos (DML) en una base de datos especificada.

Crear la macro ToggleTriggers

La macro ToggleTriggers toma un parámetro opcional, que es el nombre del proyecto de base de datos que contiene los desencadenadores que hay que actualizar. Si no especifica un nombre de proyecto, la macro solicitará uno. Podría modificar la macro para identificar en su lugar el tipo de cada proyecto en la solución y actualizar todos los proyectos de base de datos. Sin embargo, ese enfoque está fuera del ámbito de este tutorial.

Para crear la macro ToggleTriggers

  1. En el Explorador de macros, haga clic con el botón secundario del mouse en el módulo BuildActionExample y haga clic en Editar.

    Aparece la ventana Macros de Microsoft Visual Studio. Esta ventana muestra el contenido del módulo BuildActionExample.

  2. Reemplace el contenido del módulo con el código VBScript siguiente:

    Imports System
    Imports System.ComponentModel
    Imports EnvDTE
    Imports EnvDTE80
    Imports System.Diagnostics
    
    Public Module BuildActionExample
    
        ' Macro to toggle the BuildAction for all DML triggers
        ' in a database project.
        ' Before running this macro, you must:
        ' 1) Ensure that a solution file is open and saved to disk.
        ' 2) Pass in the name of a database project contained in the
        '    open solution in the dbProjName parameter. 
        Sub ToggleTriggers(Optional ByVal dbProjName As String = "")
            Dim project As Project
    
            ' if the database project name was not passed in, prompt the user for it.
            If (String.IsNullOrEmpty(dbProjName)) Then
                dbProjName = InputBox("Type the database project name.")
                If (String.IsNullOrEmpty(dbProjName)) Then
                    Return
                End If
            End If
    
            ' Loop through each project until we find the one we want
            For Each project In DTE.Solution
                Dim projectItem As EnvDTE.ProjectItem
                'Look for a project whose name matches the parameter
                If (dbProjName.Equals(project.Name)) Then
                    'Then loop through the project items, looking for
                    'the Schema Objects folder.
                    For Each projectItem In project.ProjectItems()
                        If (projectItem.Name = "Schema Objects") Then
                            ' loop through the subfolders and list the files, looking for the Tables sub-folder
                            Dim subItem As EnvDTE.ProjectItem
                            For Each subItem In projectItem.ProjectItems()
                                If (subItem.Name = "Tables") Then
                                    ' loop through looking for the Triggers subfolder
                                    Dim subsubItem As EnvDTE.ProjectItem
                                    For Each subsubItem In subItem.ProjectItems()
                                        If (subsubItem.Name = "Triggers") Then
                                            ' okay, we're in the right folder, now set the build actions
                                            Dim triggerItem As EnvDTE.ProjectItem
                                            For Each triggerItem In subsubItem.ProjectItems()
                                                'MsgBox(" trigger: " + triggerItem.Name)
                                                Dim buildAction As EnvDTE.Property
                                                buildAction = triggerItem.Properties.Item("DBProjectBuildAction")
    
                                                ' here we toggle the build action. If it was NotInBuild(0),
                                                ' we set it to Build(1). If it was Build(1), then we set it
                                                ' to NotInBuild(0).
                                                If (buildAction.Value = 0) Then
                                                    buildAction.Value = 1
                                                ElseIf (buildAction.Value = 1) Then
                                                    buildAction.Value = 0
                                                End If
                                            Next
                                        End If
                                    Next
                                End If
                            Next
                        End If
                    Next
                End If
            Next
        End Sub
    End Module
    

    La macro recorre en iteración el contenido de la solución hasta que encuentra el proyecto de base de datos cuyo nombre coincide el nombre que haya especificado. Una vez que la macro identifica ese proyecto, itera sobre los elementos de proyecto en busca de la carpeta Elementos de la solución. En la carpeta Elementos de la solución, la macro busca la carpeta Tablas y dentro de ella, busca la carpeta Desencadenadores. La macro recupera a continuación el valor de la propiedad DBProjectBuildAction para cada desencadenador. Si el valor es 1 (Compilación), se alterna a 0 (No está en la compilación). De igual forma, si el valor es 0, se alterna a 1. Aunque el nombre de la propiedad en la ventana Propiedades es Build Action, el nombre de propiedad subyacente es DBProjectBuildAction.

  3. En la ventana de macros, abra el menú Archivo y haga clic en Guardar MyMacros.

    A continuación va a crear la macro que agrega los archivos de script de un directorio al proyecto de base de datos especificado.

Crear la macro AddScriptsInDirectory

La macro AddScriptsInDirectory toma tres parámetros: el nombre del proyecto de base de datos al que desea agregar los archivos de script, el nombre de la carpeta en el proyecto de base de datos donde desea agregar los scripts y la ruta de acceso que contiene los archivos de script que la macro importará. Si no especifica estos parámetros al ejecutar la macro, se los solicitará. Si no especifica el nombre de una carpeta de proyecto en respuesta al mensaje, los archivos se agregarán a la carpeta Scripts.

Esta macro es más compleja que la anterior. Para simplificar, se genera la macro AddScriptsInDirectory creando las dos funciones siguientes y dos subrutinas:

  • Función IsFileIncluded Esta función comprueba si la extensión de un nombre de archivo especificado está en la lista de extensiones para los archivos que deberían tratarse como scripts y agregarse al proyecto de base de datos.

  • Función GetOutputWindowPane Esta función devuelve la ventana Resultados de manera que se pueda informar de los mensajes de progreso.

  • Sub AddScriptsInDirectory2 Esta subrutina toma una carpeta de proyecto y una ruta de acceso y agrega todos los archivos cuyas extensiones coinciden con la lista de extensiones de script.

  • Sub AddScriptsInDirectory Rutina de entrada para esta macro. Esta subrutina procesa los parámetros que se le pasan, realiza la validación y, o bien crea la carpeta de destino, o bien la busca en el proyecto de base de datos si la carpeta ya existe. La subrutina llama a continuación a AddScriptsInDirectory2 para agregar los archivos a esa carpeta.

Para crear la macro AddScriptsInDirectory

  1. En el Explorador de macros, haga clic con el botón secundario del mouse en el módulo ImportScriptsExample y haga clic en Editar.

    Aparece la ventana Macros de Microsoft Visual Studio. Esta ventana muestra el contenido del módulo ImportScriptsExample.

  2. Reemplace el contenido del módulo con el código VBScript siguiente:

    Imports System
    Imports EnvDTE
    Imports EnvDTE80
    Imports System.Diagnostics
    
    Public Module ImportScriptsExample
        ' A list of folder names, file names, and extensions that we want to add
        '  to the solution.
        Dim outputWindowPaneTitle As String = "Add scripts to a project folder report"
        Dim includedExtensions As New System.Collections.Specialized.StringCollection
    
        ' Function to filter out folder names, file names, and extensions that we do not 
        '  want to add to the solution.
        Function IsFileIncluded(ByVal filePath As String) As Boolean
            Dim extension As String
            Dim fileName As String
    
            extension = System.IO.Path.GetExtension(filePath)
            extension = extension.ToLower()
    
            fileName = System.IO.Path.GetFileName(filePath)
            fileName = fileName.ToLower()
    
            If (includedExtensions.Contains(extension)) Then
                Return True
            Else
                If (includedExtensions.Contains(fileName)) Then
                    Return True
                Else
                    Return False
                End If
            End If
        End Function
    
        ' This function retrieves the output window pane
        Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane
            Dim window As Window
            Dim outputWindow As OutputWindow
            Dim outputWindowPane As OutputWindowPane
    
            window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
            If show Then window.Visible = True
            outputWindow = window.Object
            Try
                outputWindowPane = outputWindow.OutputWindowPanes.Item(Name)
            Catch e As System.Exception
                outputWindowPane = outputWindow.OutputWindowPanes.Add(Name)
            End Try
            outputWindowPane.Activate()
            Return outputWindowPane
        End Function
    
        ' Given a folder within the solution and a folder on disk, add all files whose extensions
        ' are on a list of "good" extensions to the folder in the solution.
        Sub AddScriptsInDirectory2(ByVal newScriptFolder As ProjectItem, ByVal startFolder As String)
            Dim files As String()
            Dim file As String
            Dim folder As String
    
            ' get a list of files in the specified folder
            files = System.IO.Directory.GetFiles(startFolder)
    
            ' get the output window pane so we can report status
            Dim outputWindowPane As EnvDTE.OutputWindowPane
            outputWindowPane = GetOutputWindowPane(outputWindowPaneTitle, True)
    
            ' Examine all the files within the folder.
            For Each file In files
                ' if this file's extension is one we want to include...
                If (IsFileIncluded(file)) Then
                    ' try to add it to the folder
                    Dim projItem As ProjectItem
                    Try
                        projItem = newScriptFolder.ProjectItems().AddFromFile(file)
                        outputWindowPane.OutputString("The item """ + file + """ was added" + vbLf)
    
                        If (Not (projItem Is Nothing)) Then
                            If (Not (projItem.Document Is Nothing)) Then
                                projItem.Document.Close(vsSaveChanges.vsSaveChangesNo)
                            End If
                        End If
                    Catch
                        ' if an error occurs, report the failure
                        outputWindowPane.OutputString("The item """ + file + """may have not been added to the solution." + vbLf)
                    End Try
                End If
            Next
        End Sub
    
        ' creates a new subfolder within the Scripts folder in the specified database project
        ' then adds all files in the specified path to the newly created scripts sub-folder.
        Sub AddScriptsInDirectory(Optional ByVal dbProjName As String = "", Optional ByVal scriptFolderName As String = "", Optional ByVal startFolder As String = "")
            If (String.IsNullOrEmpty(dbProjName)) Then
                dbProjName = InputBox("Type the name of the database project to which you want the scripts to be imported.")
                If (String.IsNullOrEmpty(dbProjName)) Then
                    Return
                End If
            End If
    
            If (String.IsNullOrEmpty(scriptFolderName)) Then
                scriptFolderName = InputBox("Type the script folder name.")
                If (String.IsNullOrEmpty(scriptFolderName)) Then
                    scriptFolderName = "Scripts"
                End If
            End If
    
            If (String.IsNullOrEmpty(startFolder)) Then
                startFolder = InputBox("Type the folder path to import.")
                If (String.IsNullOrEmpty(startFolder)) Then
                    Return
                End If
            End If
    
            If (System.IO.Directory.Exists(startFolder) = False) Then
                MsgBox("The specified folder could not be found.")
                Return
            End If
    
            GetOutputWindowPane(outputWindowPaneTitle, True).Clear()
    
            If System.IO.Directory.Exists(startFolder) = False Then
                Dim outputWindowPane As EnvDTE.OutputWindowPane
                outputWindowPane = GetOutputWindowPane(outputWindowPaneTitle, True)
                outputWindowPane.OutputString("The path entered could not be found" + vbLf)
                Exit Sub
            End If
    
            includedExtensions = New System.Collections.Specialized.StringCollection
            ' If you do not want a file with a particular extension or name
            '  to be added, then add that extension or name to this list:
            includedExtensions.Add(".sql")
            includedExtensions.Add(".tsql")
    
            Dim newScriptFolder As ProjectItem
            Dim project As Project
    
            ' now check to see if the desired folder in the project already exists
            For Each project In DTE.Solution
                Dim projectItem As EnvDTE.ProjectItem
    
                If (dbProjName.Equals(project.Name)) Then
                    Dim found As Boolean
                    found = False
                    For Each projectItem In project.ProjectItems()
                        If (scriptFolderName.Equals(projectItem.Name)) Then
                            ' the desired folder already exists, save the projectItem that corresponds
                            ' to the folder.
                            found = True
                            newScriptFolder = projectItem
                        End If
                    Next
    
                    ' if the folder does not exist within the project, create it.
                    If (Not found) Then
                        ' the folder does not already exist, so create it
                        newScriptFolder = project.ProjectItems().AddFolder(scriptFolderName, EnvDTE.Constants.vsProjectItemKindPhysicalFolder)
                    End If
                End If
            Next
    
            ' now add the scripts in the folder to the project folder
            AddScriptsInDirectory2(newScriptFolder, startFolder)
        End Sub
    End Module
    
  3. En la ventana de macros, abra el menú Archivo y haga clic en Guardar MyMacros.

  4. En el menú Archivo, elija Cerrar y volver.

    A continuación ejecutará las macros para mostrar los resultados.

Ejecutar la macro ToggleTriggers

Si ejecuta las macros con cualquier solución distinta de la que creó en este tutorial, debe especificar el nombre del proyecto de base de datos incluido en su solución en lugar de MyAdvWorks.

Para ejecutar la macro ToggleTriggers desde la ventana de comandos.

  1. En el Explorador de soluciones, expanda el proyecto de base de datos MyAdvWorks.

  2. Expanda la carpeta Objetos de esquema.

  3. Expanda la carpeta Tablas.

  4. Expanda la carpeta Desencadenadores.

  5. En el Explorador de soluciones, haga clic con el botón secundario del mouse en cualquier desencadenador y, a continuación, haga clic en Propiedades.

    Observe el valor de la propiedad Build Action para el desencadenador que eligió.

  6. En el menú Ver, elija Otras ventanas y, a continuación, haga clic en Ventana Comandos.

    Aparecerá la Ventana Comandos.

  7. En la ventana Comando, escriba lo siguiente:

    Macros.MyMacros.BuildActionExample.ToggleTriggers MyAdvWorks
    

    MyAdvWorks es el nombre del proyecto de base de datos para cuyos desencadenadores se alternará la propiedad Build Action.

  8. Espere a que la macro finalice.

  9. Cuando la macro termine de ejecutarse, vea las propiedades para el desencadenador del paso 5.

    El valor de la propiedad Build Action es el contrario de lo que fue antes de ejecutar la macro.

    Puede ejecutar de nuevo la macro para restaurar los valores de la propiedad Build Action a sus estados originales.

    A continuación va a ejecutar la macro AddScriptsInDirectory desde el Explorador de macros.

Ejecutar la macro AddScriptsInDirectory

Si ejecuta las macros con cualquier solución distinta de la que creó en este tutorial, debe especificar el nombre del proyecto de base de datos incluido en su solución en lugar de MyAdvWorks.

Para ejecutar la macro AddScriptsInDirectory desde el Explorador de macros

  1. Si el Explorador de macros no está abierto, abra el menú Ver, seleccione Otras ventanas y haga clic en Explorador de macros.

    Aparece el Explorador de macros.

  2. En el Explorador de macros, haga clic con el botón secundario en AddScriptsInDirectory (quizá deba expandir el módulo ImportScriptsExample para mostrar la macro) y haga clic en Ejecutar.

    Aparece el cuadro de diálogo Macros de Visual Studio, que le solicita "Escriba el nombre del proyecto de base de datos al que desea que se importen los scripts".

  3. Escriba MyAdvWorks y haga clic en Aceptar.

    Aparece de nuevo el cuadro de diálogo Macros de Visual Studio, que le solicita "Escriba el nombre de la carpeta de scripts".

  4. Haga clic en Aceptar para aceptar el comportamiento predeterminado, que agregará los scripts a la carpeta Scripts.

    Aparece de nuevo el cuadro de diálogo Macros de Visual Studio, que le solicita "Escriba la ruta de acceso a la carpeta que se va a importar".

  5. Escriba la ruta de acceso donde tiene los archivos de script como se indicó anteriormente en la sección Requisitos previos en este tema. Por ejemplo, si tiene los scripts en C:\Temp, escriba C:\Temp y, a continuación, haga clic en Aceptar.

    La macro se ejecutará hasta que todos los archivos con la extensión .sql o .tsql se agreguen a la carpeta Scripts del proyecto de base de datos MyAdvWorks.

Pasos siguientes

Este tutorial muestra pequeños ejemplos de las tareas que puede realizar al utilizar el modelo de automatización de Visual Studio con sus proyectos de base de datos. Si necesita más flexibilidad, puede utilizar el modelo de automatización de un complemento de Visual Studio.

Vea también

Conceptos

Introducción a la extensibilidad de proyectos

Introducción a la terminología de Database Edition

Otros recursos

Macros de Visual Studio

Crear complementos y asistentes

Establecer referencias a los ensamblados de automatización y al objeto DTE2