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
Inicie Visual Studio si aún no lo ha hecho.
En el menú Archivo, seleccione Nuevo y, a continuación, haga clic en Proyecto.
Aparecerá el cuadro de diálogo Nuevo proyecto.
En la lista Tipos de proyecto, expanda el nodo Proyectos de base de datos y haga clic en Microsoft SQL Server.
En la lista Plantillas, haga clic en SQL Server 2005.
En Nombre, escriba MyAdvWorks y acepte los valores predeterminados para Ubicación y Nombre de la solución.
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
En el menú Ver, haga clic en Vista de esquema.
Si no estaba visible, aparece la Vista de esquema.
Haga clic en MyAdvWorks en Vista de esquema.
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.
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.
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
En el menú Ver, elija Otras ventanas y, a continuación, haga clic en Explorador de macros.
Aparece el Explorador de macros.
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.
En Nombre, escriba BuildActionExample.
Haga clic en Agregar.
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.
En Nombre, escriba ImportScriptsExample.
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
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.
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.
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
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.
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
En la ventana de macros, abra el menú Archivo y haga clic en Guardar MyMacros.
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.
En el Explorador de soluciones, expanda el proyecto de base de datos MyAdvWorks.
Expanda la carpeta Objetos de esquema.
Expanda la carpeta Tablas.
Expanda la carpeta Desencadenadores.
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ó.
En el menú Ver, elija Otras ventanas y, a continuación, haga clic en Ventana Comandos.
Aparecerá la Ventana Comandos.
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.
Espere a que la macro finalice.
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
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.
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".
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".
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".
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
Crear complementos y asistentes
Establecer referencias a los ensamblados de automatización y al objeto DTE2