Hønen og ægget

Eller historien om at slette Dynamics NAV objekter udenfor din licens.

Har du opgraderet ældre NAV’er ved du at det kan være noget djævelsk drilagtigt skidt, hvis man kommer ud for at der er et – eller flere – objekter man bare SKAL af med.

Forsøg ALTID at slette objekterne både med kundens- og din udvikler-licens.
Prøv endda med en anden kundens licens (altså naturligvis en kunde der også har ISV-modulet i sin licens).

 

Fejler alt andet, så hermed en brute force metode:

Brug af følgende kode og metode er HELT på din egen regning og risiko. Vi garanterer kun at du er helt på egen hånd hvis det går galt.

Kørslen afvikles i NAV, men laver en TXT-fil med SQL-kommandoer. Disse skal så have tilføjet et “USE <databasenavn>” og et “GO” som de første to linjer, men kan derefter afvikles på SQL-serveren.
…og ta’ lige og stop dine NAV instanser mens du gør det så de ikke bliver forvirrede:

OBJECT Codeunit 90000 SC ISV Object Killer
{
  OBJECT-PROPERTIES
  {
    Date=29-01-16;
    Time=22:12:43;
    Modified=Yes;
    Version List=SC1.00;
  }
  PROPERTIES
  {
    OnRun=VAR
            Company@1000000009 : Record 2000000006;
            Object@1000000000 : Record 2000000001;
            FileManagement@1000000008 : Codeunit 419;
            OutFile@1000000001 : File;
            ConvertFrom@1000000002 : TextConst 'ENU=."\/''%][';
            ConvertTo@1000000003 : TextConst 'ENU=________';
            SqlTableName@1000000004 : Text;
            OutFilename@1000000006 : Text;
            SaveToFilename@1000000007 : Text;
            TableNo@1000000005 : Integer;
          BEGIN
            Object.SETFILTER(Type,'<>%1&<>%2',Object.Type::FieldNumber,Object.Type::TableData);
            Object.SETRANGE(ID,1000000,98999999);
            IF Object.FINDSET THEN BEGIN
              OutFilename := FileManagement.ServerTempFileName('txt');
              OutFile.TEXTMODE(TRUE);
              OutFile.CREATE(OutFilename,TEXTENCODING::Windows);
              REPEAT
                IF Object.Type = Object.Type::Table THEN BEGIN
                  CLEAR(Company);
                  IF Company.FINDSET THEN BEGIN
                    REPEAT
                      SqlTableName := '[dbo].['+CONVERTSTR(Company.Name,ConvertFrom,ConvertTo)+'$'+CONVERTSTR(Object.Name,ConvertFrom,ConvertTo)+']';
                      OutFile.WRITE('DELETE FROM '+SqlTableName);
                    UNTIL Company.NEXT = 0;
                  END;
                END;
                TableNo := Object.ID;
                OutFile.WRITE('DELETE FROM [dbo].[Object] where (Type BETWEEN 0 AND 1) AND ID = '+FORMAT(TableNo));
                OutFile.WRITE('DELETE FROM [dbo].[Object Metadata Snapshot] where Type = 1 AND ID = '+FORMAT(TableNo));
                IF Object.Type = Object.Type::Table THEN BEGIN
                  CLEAR(Company);
                  IF Company.FINDSET THEN BEGIN
                    REPEAT
                      SqlTableName := '[dbo].['+CONVERTSTR(Company.Name,ConvertFrom,ConvertTo)+'$'+CONVERTSTR(Object.Name,ConvertFrom,ConvertTo)+']';
                      OutFile.WRITE('DROP TABLE '+SqlTableName);
                    UNTIL Company.NEXT = 0;
                  END;
                  OutFile.WRITE('');
                END;
              UNTIL Object.NEXT = 0;
              OutFile.CLOSE;
              SaveToFilename := 'RunMeOnSQLServer.txt';
              DOWNLOAD(OutFilename,'Run this file on the SQL server','','Text file(*.txt)|*.txt',SaveToFilename);
            END;
          END;
  }
  CODE
  {
    BEGIN
    {
      //SC1.00 ISV Object Killer
    }
    END.
  }
}