Helaas is de praktijk weerbarstig. Recentelijk had ik een dump van de database nodig om te testen en wie schets mijn verbazing? De import werkt niet. Ik kreeg de volgende foutmelding:
Error SQL72045: Script execution error. The executed script:
DECLARE @c AS INT = 1;
WHILE @c = 1
BEGIN
DELETE TOP (1000)
[Core].[Brand];
IF @@rowcount < 1000
SET @c = 0;
END
Op zich wazig want deze code kon ik in geen enkel script terugvinden. Kennelijk is dit iets dat de import-utility uitvoert. Na enig zoekwerk kwam ik erachter dat de importactie triggers uitvoert en één trigger veroorzaakte daarbij een probleem. Tja, daar zit je dan met je bacpac.
Na enig onderzoek bleek zo'n bacpac gewoon een zip-bestand te zijn. Even de extensie veranderen naar .zip en je kunt hem uitpakken. In dit pakket vind je een aantal bestanden. De .BCP-bestanden zijn bulkcopy bestanden en bevatten de data. Daarnaast heb je nog een aantal xml-bestanden, waaronder model.xml en Origin.xml. In model.xml zit de definitie van jouw database en dus ook de definitie van de triggers. Als je de probleemtrigger er nu eens gewoon uit haalt en hem later handmatig toevoegt? Het is het proberen waard. Het bestand weer zippen en opnieuw proberen te importeren. Helaas! Nu gaat het meteen mis. Mijn wijziging heeft ervoor gezorgd dat de checksum van de package niet meer klopt. Die checksum vind je in Origin.xml. Het fragment in kwestie staat hieronder.
<Checksums>
<Checksum Uri="/model.xml">E64500DB5070F3FF8F639D2A2570824976B3746DEAC8914E9B82652FD3696173</Checksum>
</Checksums>
<Checksum Uri="/model.xml">E64500DB5070F3FF8F639D2A2570824976B3746DEAC8914E9B82652FD3696173</Checksum>
</Checksums>
Kennelijk is de checksum alleen op model.xml toegepast hetgeen de zaak aanzienlijk vereenvoudigt en zo te zien is er een 256 bits algoritme toegepast. Nou, hoeveel kunnen dat er zijn? Laten we eens het SHA-256 algoritme uitproberen. Hieronder de listing hoe je dat in C# uitwerkt.
static void Main(string[] args)
{
SHA256Managed sha256 = new SHA256Managed();
byte[] hash;
using (FileStream stream = File.OpenRead("model.xml"))
{
hash = sha256.ComputeHash(stream);
}
StringBuilder outputString = new StringBuilder();
foreach (byte b in hash)
{
outputString.AppendFormat("{0:x2}", b);
}
Console.WriteLine(outputString.ToString().ToUpper());
Console.ReadLine();
}
Nadat de bestaande hash was vervangen voor de gegenereerde hash en de bestanden weer gezipped waren, werkte het meteen. Overigens hoef je de .zip extensie niet eens terug te veranderen in bacpac. De "Import Data-tier Application" tool blijkt het allemaal prima te begrijpen.{
SHA256Managed sha256 = new SHA256Managed();
byte[] hash;
using (FileStream stream = File.OpenRead("model.xml"))
{
hash = sha256.ComputeHash(stream);
}
StringBuilder outputString = new StringBuilder();
foreach (byte b in hash)
{
outputString.AppendFormat("{0:x2}", b);
}
Console.WriteLine(outputString.ToString().ToUpper());
Console.ReadLine();
}
Natuurlijk nog wel even de verwijderde elementen toevoegen aan de geïmporteerde database en de hele zaak draait weer als voorheen.