Scripts de creación de database de SQL Server en Visual Studio

Como parte de un proyecto ASP.NET MVC en el que estoy trabajando, trabajaré con SQL Server 2008 Express.

No estoy seguro de cómo debería tener una forma controlable de versión (estoy usando Mercurial) para volver a crear la database.

Idealmente debería ejecutarse cada vez que realizo una compilation en Visual Studio 2008.

EDITOR 1: En respuesta a algunas de las respuestas, estoy usando Visual Studio 2008 Professional Edition, que he recibido a través del progtwig Dreamspark .

Hay un par de maneras de lograr esto dependiendo de algunos de los detalles de su proyecto. Tenemos files .sql que cuando se ejecutan vuelven a crear la database. Esto permite que las secuencias de commands entren en su control de origen y sean versionadas como todo lo demás. También permite agregar scripts de cambio una vez que un producto está en producción.

Usamos esto para soltar todos los objects en nuestra database:

private static void DropDatabaseObjects() { var dropDatabaseObjects = @" /* Drop all non-system stonetworking procs */ DECLARE @name VARCHAR(128) DECLARE @constraint VARCHAR(254) DECLARE @SQL VARCHAR(254) SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'P' AND category = 0 ORDER BY [name]) WHILE @name is not null BEGIN SELECT @SQL = 'DROP PROCEDURE [dbo].[' + RTRIM(@name) +']' EXEC (@SQL) PRINT 'Dropped Procedure: ' + @name SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'P' AND category = 0 AND [name] > @name ORDER BY [name]) END /* Drop all views */ SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'V' AND category = 0 ORDER BY [name]) WHILE @name IS NOT NULL BEGIN SELECT @SQL = 'DROP VIEW [dbo].[' + RTRIM(@name) +']' EXEC (@SQL) PRINT 'Dropped View: ' + @name SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'V' AND category = 0 AND [name] > @name ORDER BY [name]) END /* Drop all functions */ SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT') AND category = 0 ORDER BY [name]) WHILE @name IS NOT NULL BEGIN SELECT @SQL = 'DROP FUNCTION [dbo].[' + RTRIM(@name) +']' EXEC (@SQL) PRINT 'Dropped Function: ' + @name SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT') AND category = 0 AND [name] > @name ORDER BY [name]) END /* Drop all Foreign Key constraints */ SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' ORDER BY TABLE_NAME) WHILE @name is not null BEGIN SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME) WHILE @constraint IS NOT NULL BEGIN SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT ' + RTRIM(@constraint) EXEC (@SQL) PRINT 'Dropped FK Constraint: ' + @constraint + ' on ' + @name SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME) END SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' ORDER BY TABLE_NAME) END /* Drop all Primary Key constraints */ SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME) WHILE @name IS NOT NULL BEGIN SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME) WHILE @constraint is not null BEGIN SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT ' + RTRIM(@constraint) EXEC (@SQL) PRINT 'Dropped PK Constraint: ' + @constraint + ' on ' + @name SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME) END SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME) END /* Drop all tables */ SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 ORDER BY [name]) WHILE @name IS NOT NULL BEGIN SELECT @SQL = 'DROP TABLE [dbo].[' + RTRIM(@name) +']' EXEC (@SQL) PRINT 'Dropped Table: ' + @name SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > @name ORDER BY [name]) END"; using (var connection = new SqlConnection(GetConnectionStringFromHibernateConfiguration("hibernate.cfg.xml"))) using (var command = new SqlCommand(dropDatabaseObjects, connection)) { connection.Open(); command.ExecuteNonQuery(); connection.Close(); } } 

Usamos esto para recrear nuestra database (suponiendo que dbScriptFolder contiene files .sql que crearán todas las tablas, vistas, processs almacenados, etc.):

 private static void RecreateDatabase() { var directoryInfo = new DirectoryInfo(ConfigurationManager.AppSettings["dbScriptFolder"]); using (var connection = new SqlConnection(GetConnectionStringFromHibernateConfiguration("hibernate.cfg.xml"))) { connection.Open(); foreach (var fileInfo in directoryInfo.GetFiles()) { if (fileInfo.Extension == ".sql") { var script = ReadFromFile(fileInfo); var server = new Server(new ServerConnection(connection)); server.ConnectionContext.ExecuteNonQuery(script); } } connection.Close(); } } 

Se recurre a estos methods en un método de testing de base para cuando ejecutamos nuestras testings de integración para que sepamos que estamos trabajando con nuestra database en un estado conocido.

Si está buscando hacer esto como parte de un script de construcción, eche un vistazo al proyecto de Tarantino aquí y aquí

Eche un vistazo a Visual Studio Team System 2008 Database Edition GDR (o DataDude )

Esto le permite almacenar y trabajar con esquemas de bases de datos y artefactos (tablas, procedimientos, activadores … prácticamente todo). También permite comparar un esquema con otro, o contra una instancia de una database y generará scripts de cambio / implementación.

También hay soporte para los datos de reference (aunque esto no es muy bueno en esta etapa de la vida útil del producto).

También hay integración con MSBuild. Ahora estoy usando esto en un proyecto grande, cada vez que hacemos una compilation, se genera un file de esquema que luego usamos para generar las secuencias de commands para aplicarlas a una database dada (Usando VSDBCMD.EXE ) Actualmente no promocionamos automáticamente estos cambios, pero hacerlo no es demasiado difícil.

¿Estás usando Visual Studio Team Suite o Visual Studio Developer Edition? Si es así, Visual Studio Database Edition es gratuito y una forma fantástica de administrar su esquema de database. Tiene todas las características que podría desear.

Cachondo