繁体   English   中英

使用Visual Studio 2010数据库项目填充静态数据的最佳实践?

[英]Best practice to populate static data using a Visual Studio 2010 database project?

如何使用Visual Studio数据库项目使用静态的源控制数据填充数据库? 我已经尝试了以下所有三种策略,发现每一种策略都比上一次更好。 我使用但不完全满意策略3.你有另一种选择吗?

  1. 将插入脚本放在“数据生成计划”文件夹中。 引用“Script.PostDeployment.sql”文件中的脚本以将其包含在部署过程中。

    - 优势:直截了当
    - 缺点:slooooooow
    - 缺点:后续部署必须首先删除静态数据或检查数据是否存在=>效率低下

  2. 使用最方便的方法(例如,可能是SSMS编辑表功能)第一次将数据插入数据库。 使用bcp命令行实用程序提取该数据,以创建一堆数据文件并将其添加到项目中。 创建“Scripts.PostDeployment.sql”文件中引用的脚本,该脚本为每个数据文件执行“批量插入”语句。

    - 优点:比插入语句快得多
    - 优点:可以利用SSMS编辑表功能
    - 缺点:每个批量插入语句都需要数据文件的完全限定文件名,因此如果数据文件位于我的机器上“C:\\ Projects \\ Dev \\ Source \\ foo.dat”,那么远程开发机器也必须将它们放在该位置或批量插入语句失败
    - 缺点:必须在后续部署中执行批量插入语句之前删除现有静态数据

  3. 在部署期间创建临时表以保存静态数据,并使用sql merge语句将这些表与目标表同步。 查看这些博文中的任何一篇。

    - 优点:似乎sql merge对问题有完美的语义
    - 缺点:在每个文件中重复此策略的逻辑 - 缺点:表定义作为sql合并文件中的临时表重复

是否有更优越的替代战略? 我放弃了策略1,因为它太慢了。 由于完全限定的文件名问题,我不喜欢策略2。 我对战略3感到满意但并不激动。是否有最好的做法?

在您的insert.sql脚本中,您可以在[__RefactorLog]表(这是部署使用的系统表)中放置一个GUID,并在插入数据之前检查此GUID是否存在,如下所示:

:setvar SOMEID“784B2FC9-2B1E-5798-8478-24EE856E62AE”//使用VS2010中的Tools \\ CreateGuid创建guid

如果不是EXISTS(SELECT [OperationKey] FROM [dbo]。[__ RefactorLog],其中[OperationKey] ='$(SOMEID)')

开始

...

INSERT INTO [dbo]。[__ RefactorLog]([OperationKey])值('$(SOMEID)')

结束

然后,只有在不存在或者您想要的情况下(通过更改Guid)才插入数据。

这是我解决这个问题的方法,以防其他人发现这个有用......

策略是在构建数据库项目之前设置sqlcmdvars变量。 此变量将包含可从后部署脚本引用的构建文件夹的绝对路径。 然后,在部署脚本中使用它可能需要的任何其他文件或资源都是一件简单的事情。 此策略的优点是所有路径都相对于项目文件,而不需要硬编码的共享路径。

创建一个新的Sql命令变量名$(MSBuildProjectDirectory)。 这将在prebuild脚本中被覆盖。

创建一个msbuild脚本,用于设置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>

更新您的部署后脚本,如下所示...

BULK INSERT [dbo].[TableName] FROM '$(MSBuildProjectDirectory)\Scripts\Post-Deployment\Data\YourDataFile.csv'
WITH (FIELDTERMINATOR = ',', ROWTERMINATOR='\n')

您可以使用数据库项目中的架构输出来更新目标数据库有一个cmd工具可以在其他机器上运行它而不是为了您的vs2010 IDE

所以你的数据仍然是相同的,除非你有任何列的下降

我们还没有将我们的VS 2010 db项目推广到Production,但是对于我们的内部项目,我们将生产数据库加载到目标数据库,并在开发/测试阶段构建/部署到它。 也就是说,我明白如果你有多个prod数据库和静态数据,那么对你来说可能不会有用。 但是,它可以用于像我们这样的单个产品分销商店。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM