Лучшая практика для заполнения статических данных с помощью проекта базы данных Visual Studio 2010?
Как вы заполняете свою базу данных статическими, контролируемыми источником данными, используя проект базы данных Visual Studio? Я пробовал все три стратегии ниже, нахожу, что каждый из них будет прогрессивно лучше, чем последний. Я использую, но не полностью удовлетворен стратегией 3. Есть ли у вас другая альтернатива?
-
Поместите скрипты вставки в папку "Data Generation Plans". Ссылка на сценарии в файле Script.PostDeployment.sql ", чтобы включить их в процесс развертывания.
- преимущество: прямолинейный
- недостаток: slooooooow
- недостаток: последующие развертывания должны сначала удалять статические данные или проверять отсутствие данных = > неэффективно
-
Вставьте данные в базу данных в первый раз, используя любой метод, который наиболее удобен (например, может быть функцией таблицы SSMS). Извлеките эти данные с помощью утилиты командной строки bcp, чтобы создать кучу файлов данных и добавить их в свой проект. Создайте script, указанный в файле Scripts.PostDeployment.sql, который выполняет оператор "объемной вставки" для каждого файла данных.
- преимущество: намного быстрее, чем инструкции вставки
- преимущество: можно использовать функцию редактирования таблицы SSMS
- недостаток: каждый оператор объемной вставки требует полного файла имени файла для файла данных, поэтому, если файлы данных расположены на моем компьютере в папке "C:\Projects\Dev\Source\foo.dat", тогда удаленная машина-разработчик также должна имейте это в этом месте, или заявка на объемную вставку не выполняется
- недостаток: необходимо удалить существующие статические данные перед выполнением операторов массовой вставки при последующих развертываниях
-
Создавайте временные таблицы во время развертывания для хранения статических данных и используйте оператор sql merge для синхронизации этих таблиц с целевыми таблицами. См. эти сообщения в блоге.
- преимущество: похоже, что sql merge имеет совершенную семантику для проблемы
- недостаток: логика для этой стратегии повторяется в каждом файле
- недостаток: определения таблиц повторяются как временные таблицы в файлах слияния sql
Существует ли альтернативная стратегия? Я отказался от стратегии 1, потому что это было слишком медленно. Мне не нравится стратегия 2 из-за проблемы с полным именем файла. Я удовлетворен, но не в восторге от стратегии 3. Есть ли наилучшая практика?
Ответы
Ответ 1
В вашем файле insert.sql script вы можете поместить GUID в таблицу [__RefactorLog] (которая является системной таблицей, используемой при развертывании), и проверить, существует ли этот GUID перед вставкой ваших данных следующим образом:
: setvar SOMEID "784B2FC9-2B1E-5798-8478-24EE856E62AE" // создать guid с помощью Tools\CreateGuid в VS2010
ЕСЛИ НЕ СУЩЕСТВУЕТ (SELECT [OperationKey] FROM [dbo]. [__ RefactorLog], где [OperationKey] = '$ (SOMEID)')
НАЧАТЬ
...
INSERT INTO [dbo]. [__ RefactorLog] ([OperationKey]) значения ('$ (SOMEID)')
КОНЕЦ
Затем вы вставляете данные только в том случае, если они не существуют или если вы хотите (путем изменения Guid).
Ответ 2
Вот как я решил эту проблему, если кто-то найдет это полезным...
Стратегия заключается в установке переменной sqlcmdvars перед созданием проекта базы данных. Эта переменная будет содержать абсолютный путь к папке сборки, на которую можно ссылаться из пост-развертывания script. Тогда было бы просто использовать это в развертывании script для любых дополнительных файлов или ресурсов, которые могут вам понадобиться. Преимущество этой стратегии состоит в том, что все пути относятся к файлу проекта, а не к жестко закодированному общему пути.
Создайте новое имя переменной команды Sql $(MSBuildProjectDirectory). Это будет переопределено в prebuild script.
Создайте msbuild script, который установит переменную командной строки sql и создаст базу данных.
<Project ToolsVersion="4.0" DefaultTargets="BuildDatabase" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
<DatabaseServer>(Local)</DatabaseServer>
<DeploymentConnectionString>Data Source=$(DatabaseServer)%3BIntegrated Security=True%3BPooling=False</DeploymentConnectionString>
<Configuration>Release</Configuration>
</PropertyGroup>
<Target Name="BuildDatabase">
<!-- Sets the projet path variable so that the post deployment script can determine the location of the bulk insert csv files. -->
<XmlUpdate
Prefix="urn"
Namespace="urn:Microsoft.VisualStudio.Data.Schema.Package.SqlCmdVars"
XmlFileName="$(MSBuildProjectDirectory)\DatabaseProjectName\Properties\Database.sqlcmdvars"
XPath="/urn:SqlCommandVariables/urn:Properties/urn:Property[urn:PropertyName='MSBuildProjectDirectory']/urn:PropertyValue"
Value="$(MSBuildProjectDirectory)\DatabaseProjectName" />
<MSBuild
Projects="DatabaseProjectName\DatabaseProjectName.dbproj"
Properties="Configuration=$(Configuration);
TargetDatabase=DatabaseName;
TargetConnectionString=$(DeploymentConnectionString);
GenerateDropsIfNotInProject=True;
BlockIncrementalDeploymentIfDataLoss=False;
DeployToDatabase=True;
IgnorePermissions=True"
Targets="Build;Deploy">
<Output TaskParameter="TargetOutputs" ItemName="SqlFiles"/>
</MSBuild>
</Target>
Обновите развертывание сообщений script следующим образом:
BULK INSERT [dbo].[TableName] FROM '$(MSBuildProjectDirectory)\Scripts\Post-Deployment\Data\YourDataFile.csv'
WITH (FIELDTERMINATOR = ',', ROWTERMINATOR='\n')
Ответ 3
Вы можете использовать вывод схемы из проекта базы данных для обновления целевой базы данных
Существует инструмент cmd для запуска на другом компьютере, а не с учетом vs2010 IDE
Таким образом, данные будут все те же, если у вас нет капель в любом столбце
Ответ 4
Мы пока не выполнили проект VSB VS 2010 в Production, но для нашего внутреннего проекта мы загружаем производственную базу данных в целевую базу данных и создаем/развертываем ее во время фазы dev/test. Тем не менее, я понимаю, что, вероятно, для вас не будет работать Тим, если у вас есть несколько баз данных prod и статические данные, выходящие за каждого. Но это может быть сделано для отдельных магазинов prod db, таких как наши.