Самый простой способ сделать копию БД SQL Server для проверки БД? - PullRequest
15 голосов
/ 20 апреля 2010

Какой самый простой способ взять базу данных SQL Server и сделать ее пробную копию?

Я просмотрел некоторые существующие темы, но не уверен, есть ли более простой способ. У меня есть издатель базы данных. Я хочу иметь возможность хранить обе базы данных на одном сервере, возможно.

Обновление: я использовал мастер публикации Microsoft SQL Server для сценария в файл, создания новой базы данных, добавления «use db» и выполнения сценария. Казалось, это работает хорошо. Присоединять / отсоединять не рекомендуется, поскольку он оставляет ссылки на исходное местоположение, если это база данных полнотекстового поиска или отсутствует журнал.

Ответы [ 4 ]

6 голосов
/ 20 апреля 2010

Я всегда просто создаю резервную копию, а затем восстанавливаю другой набор имен / файлов; Как: восстановить базу данных в новое место и имя (Transact-SQL) или вы можете создать пустую базу данных и использовать «мастер» восстановления, включающий OVERWRITE и изменяющий пути к файлам восстановления.

2 голосов
/ 20 апреля 2010

Я бы просто создал базу данных, а затем использовал задачу «Импорт данных» в SS Mgmt Studio, чтобы скопировать данные. Или вы можете создать резервную копию рабочей базы данных и восстановить ее в тестовой базе данных.

Может быть, не самый простой способ, но довольно низкий драматизм. Вы также можете записать данные в файл и воспроизвести их в новой базе данных - это займет некоторое время, но это удобно для таких вещей, как контроль версий, и это удобно для человека (ну, «разработчик») - для чтения.

1 голос
/ 20 апреля 2010

Извлечение базы данных (означает перевод ее в автономный режим), копирование файла mdf и повторное присоединение как оригинала, так и копии.

0 голосов
/ 31 декабря 2018

У меня часто есть базы данных Test и Live с одинаковой схемой. Они обычно имеют хранимые процедуры с изменениями в зависимости от состояния моих изменений в разработке. Поэтому я не всегда могу просто сделать резервную копию и восстановить. Я написал запрос, который перебирает все таблицы в базе данных, удаляет данные. Затем снова зацикливается и вставляет данные из активной базы данных. Ниже моя тестовая база данных называется WorkflowTest, а моя рабочая база называется Workflow, но вы можете просто заменить имена баз данных в переменных. Просто убедитесь, что вы подключились к базе данных TEST.

Но имена таблиц и столбцы совершенно произвольны. Я зацикливаюсь несколько раз, потому что не хочу беспокоиться об ограничениях внешнего ключа. Некоторые операции удаления / вставки завершатся неудачно, поскольку ожидается, что данные существуют в другой таблице.

Я обнаружил, что все 45 или около того моих столов полностью переполнены примерно за 2-3 цикла.

Во время цикла Вставка сначала проверяет, есть ли в таблице столбец идентификаторов, пытаясь включить IDENTITY_INSERT. Если это не сработает, то будет создан оператор вставки с предыдущим включенным IDENTITY_INSERT и выключенным следующим IDENTITY_INSERT. Это должно быть сделано в том же операторе EXEC, потому что команды в EXEC выходят из области видимости после выполнения.

Задним числом, я думаю, я мог бы написать все свои тестовые хранимые процедуры как операторы alter, восстановить тестовую базу данных из резервной копии действующей, а затем выполнить мои операторы alter. Но я считаю, что настройки безопасности пользователя не восстанавливаются должным образом, поэтому иногда это тоже может быть проблемой.

            -- Gets a list of all tables in the Test database
            -- first loops through them and deletes all records.
            --   if it encounters an error, it does not remove that table from #tablesNeedingCopy so it will try again.
            --   this is because we don't know the order to delete and may encounter foreign key constraints.
            --   It usually deletes all records from all tables after 2 or so loops.

            -- the 2nd step is nearly identical, but instead it inserts the data
            Declare @CopyToDatabase varchar(100)
            declare @CopyFromDatabase varchar(100)

            set @CopyToDatabase = 'WorkflowTest'
            set @CopyFromDatabase = 'Workflow'

            use WorkflowTest -- [Connect to Database that you want to copy to]


            DECLARE @sqlCommand varchar(max)
            declare @columnNames varchar(max)
            DECLARE @tableName as NVARCHAR(100);
            DECLARE @tableNameCursor as CURSOR;

            create table #tablesNeedingCopy
            (
                Table_Name varchar(100)
            )


            insert into #tablesNeedingCopy
            (Table_Name)
            SELECT TABLE_NAME
            FROM INFORMATION_SCHEMA.TABLES 
            WHERE TABLE_TYPE = 'BASE TABLE' 
                and Table_Name not like 'sys%'

            declare @hasTableError as char(1)
            declare @remainingTableCount int
            declare @loopControl int
            set @loopControl = 0

            select @remainingTableCount = count(*)
            from #tablesNeedingCopy

            while (@remainingTableCount > 0 And @loopControl < 10)
            begin


                set @loopControl = @loopControl + 1

                SET @tableNameCursor = CURSOR FOR
                SELECT TABLE_NAME
                FROM #tablesNeedingCopy




                OPEN @tableNameCursor;
                FETCH NEXT FROM @tableNameCursor INTO @tableName;

                WHILE @@FETCH_STATUS = 0
                BEGIN

                set @hasTableError = 'N'


                SET @sqlCommand = 'Delete from ' + @tableName
                print @sqlCommand
                begin try
                    exec (@sqlCommand)
                end try
                begin catch 
                    set @hasTableError = 'Y'
                    print ERROR_MESSAGE()
                end catch



                if (@hasTableError = 'N')
                begin
                    -- otherwise leave the table in
                    delete from #tablesNeedingCopy
                    where Table_Name = @tableName
                end

                FETCH NEXT FROM @tableNameCursor INTO @tableName;
                END

                CLOSE @tableNameCursor;
                DEALLOCATE @tableNameCursor;

                select @remainingTableCount = count(*)
                from #tablesNeedingCopy

            end -- end while


            select @remainingTableCount = count(*)
                from #tablesNeedingCopy


            if (@remainingTableCount > 0)
            begin
            select Table_Name as DeleteTableNames 
            from #tablesNeedingCopy
            end

            delete from  #tablesNeedingCopy

            -------


            insert into #tablesNeedingCopy
            (Table_Name)
            SELECT TABLE_NAME
            FROM INFORMATION_SCHEMA.TABLES 
            WHERE TABLE_TYPE = 'BASE TABLE' 
                and Table_Name not like 'sys%'

            declare @hasIdentityColumn as char(1)
            set @loopControl = 0


            select @remainingTableCount = count(*)
            from #tablesNeedingCopy

            while (@remainingTableCount > 0 And @loopControl < 10)
            begin

                set @loopControl = @loopControl + 1

                SET @tableNameCursor = CURSOR FOR
                SELECT TABLE_NAME
                from #tablesNeedingCopy




                OPEN @tableNameCursor;
                FETCH NEXT FROM @tableNameCursor INTO @tableName;

                WHILE @@FETCH_STATUS = 0
                BEGIN

                set @hasTableError = 'N'
                set @hasIdentityColumn = 'Y'

                SET @sqlCommand = 'SET IDENTITY_INSERT ' + @CopyToDatabase + '.dbo.' + @tableName + ' ON;' -- Database to copy to
                begin try
                    print @sqlCommand
                    exec (@sqlCommand)
                end try
                begin catch 
                --print  ERROR_MESSAGE() 
                set @hasIdentityColumn = 'N'
                end catch


                if (@hasTableError = 'N')
                begin
                    SELECT  top 1 @columnNames =
                        STUFF((SELECT N', ' + Column_Name 
                                FROM INFORMATION_SCHEMA.COLUMNS AS t2 
                                WHERE t2.TABLE_NAME=t.TABLE_NAME 
                                FOR XML PATH,TYPE).value(N'.','nvarchar(max)'),1,2,'')
                    FROM INFORMATION_SCHEMA.COLUMNS t
                    WHERE TABLE_NAME = @tableName
                    order by ORDINAL_POSITION


                    set @sqlCommand = 'Insert into ' + @CopyToDatabase + '.dbo.' + @tableName + ' (' + @columnNames + ') select ' + @columnNames + ' from ' + @CopyFromDatabase + '.dbo.' + @tableName 

                    if (@hasIdentityColumn = 'Y')
                    begin
                    set @sqlCommand = 'SET IDENTITY_INSERT ' + @CopyToDatabase + '.dbo.' + @tableName + ' ON; ' + @sqlCommand + ' SET IDENTITY_INSERT ' + @CopyToDatabase + '.dbo.' + @tableName + ' OFF;'
                    end
                    print @sqlCommand
                    begin try
                        exec (@sqlCommand)
                    end try
                    begin catch
                        set @hasTableError = 'Y'
                        print ERROR_MESSAGE()
                    end catch
                end


                if (@hasTableError = 'N')
                begin
                    -- otherwise leave the table in
                    delete from #tablesNeedingCopy
                    where Table_Name = @tableName
                end

                FETCH NEXT FROM @tableNameCursor INTO @tableName;
                END

                CLOSE @tableNameCursor;
                DEALLOCATE @tableNameCursor;

                select @remainingTableCount = count(*)
                from #tablesNeedingCopy

            end -- end while

            select @remainingTableCount = count(*)
                from #tablesNeedingCopy


            if (@remainingTableCount > 0)
            begin
            select Table_Name as InsertTableNames 
            from #tablesNeedingCopy
            end

            drop table #tablesNeedingCopy
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...