2010-11-25 2 views
24

Wie befüllen Sie Ihre Datenbank mit statischen, quellengesteuerten Daten mithilfe eines Visual Studio-Datenbankprojekts? Ich habe alle drei Strategien ausprobiert und festgestellt, dass jeder Schritt besser ist als der letzte. Ich benutze, aber nicht vollständig mit Strategie 3. Haben Sie eine andere Alternative?Bewährte Methode zum Auffüllen statischer Daten mit einem Visual Studio 2010-Datenbankprojekt?

  1. Platzieren Sie Skripte in den Ordner "Data Generation Plans". Verweisen Sie die Skripts in der Datei "Script.PostDeployment.sql", um sie in den Bereitstellungsprozess einzubeziehen.

    - Vorteil: straight-forward
    - Nachteil: slooooooow
    - Nachteil: nachfolgende entfalten muss zunächst statische Daten löschen oder für Nicht-Existenz von Daten prüfen => ineffizient

  2. Legen Sie die Daten in die Datenbank das erste Mal mit der Methode, die am bequemsten ist (z. B. die SSMS-Tabellenfunktion). Extrahieren Sie diese Daten mit dem bcp-Befehlszeilendienstprogramm, um eine Reihe von Datendateien zu erstellen und sie Ihrem Projekt hinzuzufügen. Erstellen Sie ein Skript, auf das in der Datei "Scripts.PostDeployment.sql" verwiesen wird, das für jede Datendatei eine Anweisung "Masseneinfügung" ausführt.

    - Vorteil: viel schneller als Insert-Anweisungen
    - Vorteil: kann SSMS nutzen bearbeiten Tabellenfunktion
    - Nachteil: jede Anweisung von Bulk einen vollständig qualifizierten Dateinamen der Datendatei erfordert also, wenn die Datendateien befinden sich auf meinem Rechner unter "C: \ Projects \ Dev \ Source \ foo.dat", dann muss der Remote-Dev-Rechner sie auch an diesem Ort haben oder die Bulk-Insert-Anweisung schlägt fehl
    - Nachteil: muss vorhandene statische Daten vor löschen Ausführen von Masseneinfügeanweisungen für nachfolgende Bereitstellungen

  3. Erstellen Sie während der Bereitstellung temporäre Tabellen, um die statischen Daten zu speichern Verwenden Sie die Anweisung sql merge, um diese Tabellen mit den Zieltabellen zu synchronisieren. Siehe either von these Blogposts.

    - Vorteil: scheint, wie SQL-Merge hat die perfekte Semantik für das Problem
    - Nachteil: die Logik für diese Strategie in jeder Datei wiederholt wird - Nachteil: Tabellendefinitionen als temporäre Tabellen in der SQL wiederholt Dateien zusammenführen

Gibt es eine überlegene alternative Strategie? Ich habe Strategie 1 aufgegeben, weil es zu langsam war. Ich mag Strategie 2 aufgrund des voll qualifizierten Dateinamens nicht. Ich bin zufrieden, aber nicht begeistert von Strategie 3. Gibt es eine Best Practice?

+0

Haben Sie die Möglichkeit, die Daten in der Zieldatenbank zu verlassen, anstatt sie jedes Mal neu zu bevölkern? –

+0

@David: Ich glaube nicht, dass es eine solche Option gibt, es sei denn jemand kann mir etwas anderes sagen. Es muss irgendwie Teil der skriptgesteuerten Lösung sein. Strategie 3 behandelt dies mit dem Zusammenführungsbefehl. Strategie 1 müsste geändert werden, um zuerst zu prüfen, ob die Daten vor dem Einfügen existieren. Das Gleiche gilt für Strategie 2. –

+0

Es ist wahrscheinlich kein Trost für Sie, aber wir haben gerade SQL Source Control 2 veröffentlicht, das statische Daten unterstützt. Leider unterstützt dies das Datenbankprojekt nicht - Zumindest noch nicht. Wir denken jedoch ernsthaft darüber nach. Wenn Sie interessiert sind, stimmen Sie bitte hier ab: http://redgate.uservoice.com/forums/39019-sql-source-control/suggestions/1010465-work-with-a-visual-studio-2010-database- Projekt? Ref = Titel –

Antwort

0

Wir haben unser VS 2010 db-Projekt noch nicht in die Produktion implementiert, aber für unser Inhouse-Projekt laden wir die Produktionsdatenbank in die Zieldatenbank und bauen/implementieren sie während der Entwicklungs-/Testphase. Das heißt, ich verstehe, dass wahrscheinlich nicht für Sie Tim arbeiten wird, wenn Sie mehrere Prod-Datenbanken und statische Daten haben, die für jeden ausgeht. Aber es kann für Single-Prod-Db-Shops wie unserer getan werden.

+1

Danke für die Antwort. Macht es Ihnen etwas aus, mir ein bisschen mehr Details zu geben? Also sichern Sie prod, stellen Sie es auf das Ziel zurück (daher hat target alle Daten) und führen Sie dann deploy von VS aus, um die Schemas zu synchronisieren? Wenn das stimmt, dann scheint es, als ob Sie nicht verhindern können, dass jemand Daten zu prod hinzufügt, die dann zum Ziel propagieren. Ich suche nach einer quellengesteuerten Art zu sagen: "Dies sind unsere Basisdaten und nachdem ich auf Deploy geklickt habe, bin ich mir sicher, dass es auf dem Ziel existiert." Folglich würde die gleiche Methode auch unterstützen: "Hier ist eine Sammlung von Daten, die einen Testfall bildet, der wiederholt einsetzbar ist" –

8

In Ihrem Einsatz.sql script, können Sie eine GUID in die [__RefactorLog] -Tabelle (eine von der Bereitstellung verwendete Systemtabelle) setzen und überprüfen, ob diese GUID vorhanden ist, bevor Sie Ihre Daten wie folgt einfügen:

: setvar SOMEID "784B2FC9-2B1E-5798 -8478-24EE856E62AE“// create guid mit tools \ CreateGUID in VS2010

IF NOT EXISTS (SELECT [OperationKey] FROM [dbo]. [__ RefactorLog] wobei [OperationKey] = '$ (SOMEID)')

BEGIN

...

INSERT INTO [dbo]. [__ RefactorLog] ([OperationKey]) values ​​('$ (SOMEID)')

END

Dann legen Sie Daten nur dann, wenn nicht vorhanden, oder wenn Sie wollen (durch die Guid zu ändern) .

1

Sie können das Schema Ausgabe aus dem Datenbank-Projekt verwenden, um die Zieldatenbank zu aktualisieren Es ist ein cmd-Tool es auf anderen Rechnern laufen mit nicht im Hinblick auf Sie VS2010 IDE

So werden Sie Daten noch sein das gleiche, es sei denn, Sie Tropfen auf einer beliebigen Spalte

2

diese haben ist, wie ich dieses Problem falls jemand gelöst sonst findet dies nützlich ...

die Strategie eine sqlcmdvars Variable gesetzt ist, bevor das Datenbankprojekt zu bauen. Diese Variable enthält den absoluten Pfad zum Build-Ordner, auf den vom Post-Bereitstellungsskript verwiesen werden kann. Dann wäre es eine einfache Sache, das im Bereitstellungsskript für zusätzliche Dateien oder Ressourcen zu verwenden, die Sie möglicherweise benötigen. Der Vorteil dieser Strategie besteht darin, dass alle Pfade relativ zur Projektdatei sind, anstatt einen fest codierten gemeinsamen Pfad zu benötigen.

Erstellen Sie einen neuen Sql-Befehlsvariablennamen $ (MSBuildProjectDirectory). Dies wird im Prebuild-Skript überschrieben.

Erstellen Sie ein Msbuild-Skript, das die SQL-Befehlsvariable festlegen und die Datenbank erstellen würde.

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

Aktualisieren Sie Ihren Bereitstellungsskript Beitrag wie folgt ...

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