2010-11-25 17 views
24

¿Cómo llenas tu base de datos con datos estáticos controlados por código fuente usando un proyecto de base de datos de Visual Studio? He intentado las tres estrategias a continuación, encontrando que cada una es progresivamente mejor que la anterior. Estoy usando pero no estoy completamente satisfecho con la estrategia 3. ¿Tienes otra alternativa?¿Práctica recomendada para rellenar datos estáticos con un proyecto de base de datos de Visual Studio 2010?

  1. Coloque scripts de inserción en la carpeta "Planes de generación de datos". Haga referencia a los scripts en el archivo "Script.PostDeployment.sql" para incluirlos en el proceso de implementación.

    - ventaja: recta de avance
    - inconveniente: muuuuy lento
    - inconveniente: se despliega subsiguientes deben eliminar primero los datos estáticos o detectar la no existencia de datos => ineficiente

  2. insertar los datos en la base de datos la primera vez utilizando el método más conveniente (por ejemplo, podría ser la función de tabla de edición SSMS). Extraiga esos datos utilizando la utilidad de línea de comandos de bcp para crear un grupo de archivos de datos y agréguelos a su proyecto. Cree una secuencia de comandos a la que se hace referencia en el archivo "Scripts.PostDeployment.sql" que ejecuta una instrucción de "inserción masiva" para cada archivo de datos.

    - ventaja: mucho más rápido que las declaraciones de inserción
    - ventaja: puede aprovechar SSMS utilidad de tablas de edición
    - inconveniente: cada declaración inserción masiva requiere un nombre de archivo completo para el archivo de datos de modo que si los archivos de datos están ubicados en mi máquina en "C: \ Projects \ Dev \ Source \ foo.dat", entonces el equipo de desarrollo remoto también debe tenerlos en esa ubicación o la instrucción de inserción masiva falla
    - drawback: debe eliminar los datos estáticos existentes antes ejecución de instrucciones de inserción masiva en despliegues posteriores

  3. Cree tablas temporales durante la implementación para contener los datos estáticos d use la instrucción de fusión sql para sincronizar estas tablas con las tablas de destino. Ver either de these publicaciones en el blog.

    - ventaja: que parece mezcla de SQL tiene la semántica perfectas para el problema
    - inconveniente: la lógica de esta estrategia se repite en cada archivo - inconveniente: definiciones de las tablas se repiten en forma de tablas temporales en el sql combinar archivos

¿existe una estrategia alternativa superior? Dejé la estrategia 1 porque era demasiado lenta. No me gusta la estrategia 2 debido al problema del nombre de archivo completo. Estoy satisfecho pero no emocionado con la estrategia 3. ¿Existe una mejor práctica?

+0

¿Tiene la opción de dejar los datos en la base de datos de destino, en lugar de volver a poblar cada vez? –

+0

@David: No creo que exista tal opción a menos que alguien me diga lo contrario. Tiene que ser parte de la solución guionizada de alguna manera. La estrategia 3 maneja esto con el comando de fusión. La estrategia 1 tendría que modificarse para verificar primero si los datos existen antes de insertarlos. Del mismo modo para la estrategia 2. –

+0

Probablemente no sea un consuelo para usted, pero acabamos de lanzar SQL Source Control 2, que tiene Static Data Support. Lamentablemente, esto no es compatible con el proyecto de base de datos - Todavía no, al menos. Sin embargo, estamos considerando seriamente esto. Si está interesado, vote aquí: http://redgate.uservoice.com/forums/39019-sql-source-control/suggestions/1010465-work-with-a-visual-studio-2010-database- project? ref = title –

Respuesta

0

Todavía no hemos rodado nuestro proyecto db VS 2010 en producción, pero para nuestro proyecto interno cargamos la base de datos de producción en la base de datos de destino y la construimos/implementamos durante la fase de desarrollo/prueba. Dicho esto, entiendo que probablemente Tim no funcione para usted si tiene varias bases de datos prod y datos estáticos que va a cada uno. Pero, se puede hacer para tiendas single db db como la nuestra.

+1

Gracias por la respuesta. ¿Te importa darme un poco más de detalle? Entonces, ¿hace una copia de seguridad de prod, lo restaura al objetivo (por lo tanto, el objetivo tiene todos los datos), luego ejecuta la implementación de VS para sincronizar los esquemas? Si eso es cierto, parece que no se puede evitar que alguien agregue datos al prod, lo que luego se propagará al objetivo. Estoy buscando una forma controlada por la fuente de decir: "Esta es nuestra base de datos y luego de hacer clic en implementar, estoy seguro de que existe en el objetivo". Por corolario, el mismo método también apoyaría: "Aquí hay una colección de datos que forma un caso de prueba que se puede desplegar repetidamente" –

8

En su inserto.secuencia de comandos SQL, se puede poner un GUID en la tabla [__RefactorLog] (que es una tabla del sistema utilizado por la implementación) y comprobar si existe este GUID antes de insertar los datos de la siguiente manera:

: SOMEID setvar "784B2FC9-2B1E-5798 -8478-24EE856E62AE" // crear gUID Tools \ CreateGuid en VS2010

SI NO EXISTE (SELECCIONAR [OperationKey] de [dbo]. [__ RefactorLog] donde [OperationKey] = '$ (SOMEID)')

COMENZAR

...

INSERT EN [dbo]. [__ RefactorLog] ([OperationKey]) valores ('$ (SOMEID)')

FIN

A continuación se insertan datos sólo si no existe o si quieres (al cambiar el GUID) .

1

Puede usar la salida del esquema del proyecto de base de datos para actualizar la base de datos destino Hay una herramienta cmd para ejecutarlo en otra máquina no está con la vista de que el IDE VS2010

Así que unos datos todavía el mismo, a menos que tenga gotas en cualquier columna

2

Así es como he resuelto este problema en el caso de cualquier otra persona encuentra este útil ...

la estrategia consiste en establecer una variable sqlcmdvars antes de construir el proyecto de base de datos. Esta variable contendría la ruta absoluta a la carpeta de compilación a la que se puede hacer referencia desde el script de despliegue posterior. Entonces sería una simple cuestión usar eso en el script de implementación para cualquier archivo o recurso adicional que pueda necesitar. La ventaja de esta estrategia es que todas las rutas son relativas al archivo de proyecto en lugar de requerir una ruta compartida codificada.

Cree un nuevo nombre de variable de comando Sql $ (MSBuildProjectDirectory). Esto se sobrescribirá en el script de precompilación.

Cree un script de msbuild que establezca la variable de comando sql y cree la base de datos.

<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> 

actualización de su script de implementación posterior de la siguiente manera ...

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