Сценарии создания базы данных SQL Server в Visual Studio - PullRequest
2 голосов
/ 22 января 2010

Как часть проекта ASP.NET MVC, над которым я работаю, я буду работать с SQL Server 2008 Express.

Я не уверен, как мне поступить с управлением версиями(Я использую Mercurial) способ воссоздания базы данных.

В идеале его следует запускать каждый раз, когда я выполняю сборку в Visual Studio 2008.

РЕДАКТИРОВАТЬ 1: В ответ на паруответы, я использую Visual Studio 2008 Professional Edition, которую я получил через программу Dreamspark .

Ответы [ 3 ]

2 голосов
/ 22 января 2010

Взгляните на Visual Studio Team System 2008 Database Edition GDR (или DataDude )

Это позволяет хранить и работать со схемами базы данных и артефактами (таблицами, процедурами, триггерами ... практически всем). Он также позволяет сравнивать одну схему с другой или с экземпляром базы данных и генерирует сценарии изменения / развертывания.

Также есть поддержка справочных данных (хотя это не очень хорошо на данном этапе жизненного цикла продуктов).

Существует также интеграция с MSBuild - сейчас я использую это в большом проекте, каждый раз, когда мы делаем сборку, генерируется файл схемы, который мы затем используем для фактического создания сценариев для применения к данной базе данных (Использование VSDBCMD.EXE). В настоящее время мы не автоматически выталкиваем эти изменения, но это не так уж сложно.

2 голосов
/ 22 января 2010

Есть несколько способов сделать это в зависимости от некоторых особенностей вашего проекта. У нас есть файлы .sql, которые при выполнении воссоздают базу данных. Это позволяет сценариям входить в систему управления версиями и иметь версии, как и все остальное. Он также позволяет добавлять сценарии изменений после того, как продукт находится в производстве.

Мы используем это, чтобы отбросить все объекты в нашей базе данных:

private static void DropDatabaseObjects()
    {
        var dropDatabaseObjects =
            @"
                    /* Drop all non-system stored 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();
        }
    }

Мы используем это для воссоздания нашей базы данных (при условии, что dbScriptFolder содержит файлы .sql, которые будут создавать все таблицы, представления, сохраненные процедуры и т. Д.):

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();
        }
    }

Эти методы вызываются в методе base testfixture, когда мы запускаем наши интеграционные тесты, чтобы мы знали, что мы работаем с нашей базой данных в известном состоянии.

Если вы хотите сделать это как часть сценария сборки, взгляните на проект Tarantino здесь и здесь

0 голосов
/ 22 января 2010

Вы используете Visual Studio Team Suite или Visual Studio Developer Edition? В этом случае Visual Studio Database Edition является бесплатным и фантастическим способом управления схемой базы данных. Имеет все функции, которые вы можете захотеть.

Randy

...