2016-12-30 9 views
1

Я пытаюсь скопировать базу данных SQL Server в новую базу данных на том же сервере без передачи данных (то есть, я пытаюсь создать идентичный , пустая база данных).Сбой SMO.Transfer из-за входа в систему LocalAdmin, но только для некоторых баз данных

Приведенный ниже код корректно работает с образцовой базой данных, созданной специально для тестирования. Но когда применяется к фактической целевой базе данных, она терпит неудачу при вызове .TransferData() (после нескольких секунд выполнения) с ошибкой System.Data.SqlClient.SqlException : 'LocalAdmin' is not a valid login or you do not have permission. Учетная запись, под которую я разрабатываю и тестирую программу, может использоваться для входа в экземпляр SQL Server, о котором идет речь, и выполнять создание базы данных и создавать объекты как в исходной, так и в целевой базе данных.

После сбоя база данных, указанная в targetDb , имеет, по сути, была создана, но в ней нет таблиц или других структур.

Может ли кто-нибудь сказать мне, как исправить следующий код, чтобы он смог успешно скопировать мою структуру базы данных?

/* Ref: Microsoft.SqlServer.ConnectionInfo.dll 
     Microsoft.SqlServer.Management.Sdk.Sfc.dll 
     Microsoft.SqlServer.Smo.dll 
     Microsoft.SqlServer.SmoExtended.dll 
     Microsoft.SqlServer.SqlEnum.dll */ 

using Microsoft.SqlServer.Management.Smo; 
using System; 
using System.Diagnostics; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      CopyEmptyDatabase(@"server_name\instance_name", "sourceDb_name", "targetDb_name"); 
     } 

     public static void CopyEmptyDatabase(string instance, string sourceDb, string targetDb) 
     { 
      var server = new Server(instance); 

      var transferAgent = new Transfer(server.Databases[sourceDb]); 

      transferAgent.CopyAllObjects = true; 
      transferAgent.DropDestinationObjectsFirst = true; 
      transferAgent.CopySchema = true; 
      transferAgent.CopyData = false; 

      // Transfer requires the target DB to exist 
      var target = new Database(server, targetDb); 
      target.Create(); 

      transferAgent.DestinationServer = instance; 
      transferAgent.DestinationDatabase = targetDb; 
      transferAgent.DestinationLoginSecure = true; 
      transferAgent.Options.IncludeIfNotExists = true; 

      try 
      { 
       transferAgent.TransferData(); 
      } 
      catch (Exception exc) 
      { 
       Debug.Print(exc.Message); 
       throw; 
      } 

     } 
    } 
} 
+0

Когда вы создаете новую базу данных, какие логин и пользователь вы используете для добавления схем? –

+0

Также как SSMS имеет сценарии, которые делают весь этот процесс быстрым. Щелкните правой кнопкой мыши по базе данных в своем проекте Explorer, выберите команду «Сценарии» и установите флажок, чтобы добавить все соответствующие объекты для всего. Существует опция включения схемы и метаданных, но по умолчанию она настроена только на ваши схемы. –

+0

Нет воспроизведения. Ваш код отлично работает для меня. –

ответ

1

Попробуйте создать новый db из инструментов SQL и посмотрите, можете ли вы сбросить sprocs, которые находятся во вновь созданной базе данных. Если вы не являетесь dbo, у вас, вероятно, не будет прав на их удаление. Обратите внимание, что объекты в нем скопированы из model db ... поэтому он не будет полностью пустым в начале. Возможно, ваша организация добавила вещи в model ... так что вам нужно будет изучить это.

Edit:

Другой способ проверить эту теорию ... просто удалить строку, которая говорит transferAgent.DropDestinationObjectsFirst = true;

0
  • вопросы Вход может быть связано с учетной записью службы, что запрос работает под управлением. Например, репликация использует учетную запись агента SQL Server по умолчанию для чтения в файл-файл. Это также относится к тому, какая учетная запись пытается войти в целевую базу данных.
  • никогда не пишите в текстовые пароли.
  • убедитесь, что SUSER_ID совпадает с логическим, два идентичных, но обычный логин/пользователи будут отличаться друг от друга.

Постарайтесь не изобретать велосипед, когда он уже доступен. Если это приложение (звучит рискованно), использование уже имеющихся у вас инструментов позволит сэкономить время, создать стабильные файлы .sql и помочь контролировать ваши изменения в любых средах PROD.

Как правило, если я изменяю что-либо на уровне схемы для PROD-сервера, я сохраняю сценарий или предыдущие схемы перед его внедрением. Вы никогда не знаете, когда это может спасти вашу жизнь.

  1. Используйте SSMS и выберите GENERATE SCRIPTS Generate Scripts В вашем Object Explorer, щелкните правой кнопкой мыши на целевой базе данных. На вкладке Tasks выберите Generate Scripts...

    • По умолчанию параметры установлены, чтобы воссоздать все основные (tables, schemas, Stored Procedures и т.д.) объектов, но это не включает в себя некоторые нематериальные параметры, такие как данные.
  2. Установить местоположение Set Scripting Options Установить местоположение ваших сценариев, такие как общая папка, что каждый может найти.

    • Если вы можете избежать Unicode скриптов, используйте параметр ANSI, как и любые крупные .sql файлов потребуется SQLCMD для выполнения.
    • В качестве альтернативы вы можете разделить объекты на свои собственные файлы, чтобы разрешить контроль версий.
  3. Используйте дополнительные параметры Set the environment Вы можете установить уровень версии ваших сценариев (еще в SQL Server 2005) и тип двигателя базы данных.
    • Вы будете указать логинов, Права доступа на уровне объектов, Владельцев, и даже может необязательно включать статистики и их гистограмм если тесты такие же, как среды PROD. В общем, пусть оптимизатор справится с этим.
    • Другие объекты, такие как Triggers, могут не включаться, поэтому обязательно перейдите по списку для своей среды.
  4. Наслаждайтесь новыми сценариями .sql! Enjoy!!! Вот и все!

Самая лучшая часть этого используется нативный SSMS клиент для создания и вы иметь законные .sql файлы, любая версия SQL Server сможет читать.

+2

Спасибо. Как следует из кода, это, по сути, приложение. –

+0

@ Larry.Lustig быть как может, это, возможно, глупо создавать такую ​​вещь. Во-первых, приложение потребуется рядом с правами sysadmin, и даже тогда, как предотвратить это от злоупотреблений? Вы не ошиблись в своей оценке в теории, и я сделал это в начале. –

+0

Это внутренняя утилита, позволяющая нам запутывать базы данных, чтобы сделать их безопасными для развития в нашей организации. Я, конечно, не собираюсь хранить учетные данные в приложении, либо в виде обычного текста, либо в противном случае. Если для входа в систему Windows, под которой запущена утилита, недостаточно для предоставления учетных данных, необходимых для завершения '.TransferData()', тогда я рад, что пользователь вводит временные учетные данные как часть утилиты. –