29.08.18 Navision Navision

Von: Peter Karsten

Daten Übernahme Dynamics NAV 2009 -> 2018

Es stellte sich die Frage wie man am besten und schnellsten Daten aus einer MS Dynamics NAV 2009 SQL Datenbank in eine Dynamics NAV 2018 SQL Datenbank bekommt. Eine Methode könnte folgende sein:

Tabellen & Felder Relationen

Die Tabelle "Field" (2000000041) ist eine Virtuelle Tabelle welche Informationen zu Tabellen und Feldern bereitstellt. In NAV2009 kann dafür ein Form erstellt werden, Source Table ist Field, und alle auswählbaren Felder, ergibt folgende Ansicht: 

 

 

Dynamics Nav 2009 - Tabelle Field

 

In NAV 2018 wird eine List Page erstellt, die ausgewählte Tabelle Field und alle verfügbaren Felder ergibt folgende Ansicht:

 

Dynamics NAV 2018 - Tabelle Field

 

Ich habe mir dann ein Excel Dokument erstellt mit 2 Arbeitsmappen (NAV2009,NAV2018). Dorthin habe ich jeweils die Daten aus dem Form bzw. der Page hineinkopiert (Strg+A, Strg+C, Strg+V)  :-)

 

 

Excel Tabelle mit den kopierten Werten aus der Tabelle Field


Nun erstelle ich eine Datenbank in welche ich die Werte aus der Excel Tabelle importieren möchte: 

USE master; 
GO 
IF DB_ID (N'NAV_FIELDS_DB') IS NOT NULL
DROP DATABASE NAV_FIELDS_DB;
GO
CREATE DATABASE NAV_FIELDS_DB; 
GO

Import der Excel Arbeitsmappen:

SSMS Daten importieren
Excel Datei wählen
Ziel Datenbank wählen
...
Arbeitsmappen wählen
Sofort ausführen
Import fertig
Die neu angelegten Tabellen
und deren Inhalt


Nun erstelle ich eine Tabelle in welcher ich Daten aus den vorher angelegten Tabellen zusammenfassen möchte: 

USE NAV_FIELDS_DB
GO
CREATE TABLE [dbo].[NavFields09vs18](
    [TableNo] [int] NOT NULL,
    [TableName2009] [nvarchar](255) NULL,
    [FieldName2009] [nvarchar](255) NULL,
    [FieldNo] [int] NOT NULL,
    [FieldName2018] [nvarchar](255) NULL,
    [FieldNeededIn2018] [int] NULL,
    [TableName2018] [nvarchar](255) NULL,
    [TableDeletedIn2018] [int] NULL,
    [TableChangedNameIn2018] [int] NULL,
    [FieldName2009ChangedIn2018] [int] NULL,
    [Type2018] [nvarchar](255) NULL,
    [Class2018] [nvarchar](255) NULL,
    [Enabled2018] [nvarchar](255) NULL,
    [Type2009] [nvarchar](255) NULL,
    [Class2009] [nvarchar](255) NULL,
    [Length2009] [int] NULL,
    [Length2018] [int] NULL,
    [FieldNameLengthChanged] [int] NULL,
    [FieldTypeChanged] [int] NULL
) ON [PRIMARY]
GO

 

Filtern der Daten um hilfreiche Informationen zu bekommen, und Übernahme in die neue Tabelle:

 

-- Vorhandene Datensätze löschen
DELETE FROM NavFields09vs18

-- Übernimmt alle Felder aus Tabelle NAV2018
INSERT INTO NavFields09vs18 (TableNo,TableName2018,FieldNo,FieldName2018 ,FieldNeededIn2018, Type2018, Class2018, Enabled2018, Length2018)
SELECT TableNo,TableName,No,FieldName, 0, Type, Class, Enabled,Len FROM NAV18$


-- Updatet alle Feldnamen2018 in NavFields09vs18  welche TableNo und FeldNo gleich sind
UPDATE NavFields09vs18  SET FieldName2009 = (SELECT FieldName FROM Nav2009$ WHERE NavFields09vs18.TableNo = Nav2009$.TableNo AND NavFields09vs18.FieldNo = Nav2009$.No)
UPDATE NavFields09vs18  SET TableName2009 = (SELECT TableName FROM NAV2009$ WHERE NavFields09vs18.TableNo = Nav2009$.TableNo AND NavFields09vs18.FieldNo = Nav2009$.No)
UPDATE NavFields09vs18  SET Type2009 = (SELECT Type FROM NAV2009$ WHERE NavFields09vs18.TableNo = Nav2009$.TableNo AND NavFields09vs18.FieldNo = Nav2009$.No)
UPDATE NavFields09vs18  SET Class2009 = (SELECT Class FROM NAV2009$ WHERE NavFields09vs18.TableNo = Nav2009$.TableNo AND NavFields09vs18.FieldNo = Nav2009$.No)
UPDATE NavFields09vs18  SET Length2009= (SELECT Len FROM NAV2009$ WHERE NavFields09vs18.TableNo = Nav2009$.TableNo AND NavFields09vs18.FieldNo = Nav2009$.No)

-- 2009er Feldname hat sich in 2018 geändert
UPDATE NavFields09vs18  SET FieldName2009ChangedIn2018 =  CASE  WHEN FieldName2018 <> FieldName2009 THEN 1 ELSE 0 END
-- 2009er Tabellenname hat sich in 2018 geändert
UPDATE NavFields09vs18  SET TableChangedNameIn2018 =  CASE  WHEN TableName2018 <> TableName2009 THEN 1 ELSE 0 END
-- 2009er Tabelle wurde in 2018 gelöscht
UPDATE NavFields09vs18  SET TableDeletedIn2018 = CASE  WHEN NOT EXISTS (SELECT 1 FROM nav18$ WHERE TableNo = [nav18$].[TableNo]) THEN 1 ELSE 0 END
-- 2009er Feld Länge hat sich in 2018 geändert
UPDATE NavFields09vs18  SET FieldNameLengthChanged =  CASE  WHEN Length2009 <> Length2018 THEN 1 ELSE 0 END
-- 2009er FeldTyp hat sich in 2018 geändert
UPDATE NavFields09vs18  SET FieldTypeChanged =  CASE  WHEN Type2009 <> Type2018 THEN 1 ELSE 0 END

--Select all entries
SELECT * FROM [NAV_FIELDS_DB].[dbo].[NavFields09vs18] ORDER by TableNo, FieldNo ASC

--Changed TableNames
SELECT TableNo, TableName2009,TableName2018, TableChangedNameIn2018 FROM NavFields09vs18 WHERE TableChangedNameIn2018 = 1 GROUP BY TableChangedNameIn2018, TableNo, TableName2009,TableName2018

--Changed FieldNames
SELECT TableNo, FieldNo, TableName2009,TableName2018, FieldName2009, FieldName2018,FieldName2009ChangedIn2018 FROM NavFields09vs18 WHERE FieldName2009ChangedIn2018 = 1 GROUP BY TableNo, FieldNo, TableName2009,TableName2018, FieldName2009, FieldName2018, FieldName2009ChangedIn2018

--Changed FieldTypes
SELECT TableNo, FieldNo, TableName2009,TableName2018, FieldName2009, FieldName2018,Type2009,Type2018,FieldTypeChanged FROM NavFields09vs18 WHERE FieldTypeChanged = 1 GROUP BY TableNo, FieldNo, TableName2009,TableName2018, FieldName2009, FieldName2018, Type2009,Type2018,FieldTypeChanged

--Changed FielLength
SELECT TableNo, FieldNo, TableName2009,TableName2018, FieldName2009, FieldName2018, Length2009,Length2018, FieldNameLengthChanged FROM NavFields09vs18 WHERE FieldNameLengthChanged = 1 GROUP BY TableNo, FieldNo, TableName2009,TableName2018, FieldName2009, FieldName2018, Length2009,Length2018,FieldNameLengthChanged

--Changed FieldLength is smaller
SELECT TableNo, FieldNo, TableName2009,TableName2018, FieldName2009, FieldName2018, Length2009,Length2018, FieldNameLengthChanged FROM NavFields09vs18 WHERE (FieldNameLengthChanged = 1 AND Length2009 > Length2018) GROUP BY TableNo, FieldNo, TableName2009,TableName2018, FieldName2009, FieldName2018, Length2009,Length2018,FieldNameLengthChanged

--Show 2009 Custom / individual Fields not existents in 2018
SELECT TableNo, TableName, FieldName, No FROM  [NAV2009$] WHERE [NAV2009$].[No] > 49999 AND [NAV2009$].[No] < 51000

Eine C# Konsolenanwendung dient mir dazu das T-SQL für die Datenübernahme zu generieren. Um es schnell zu machen habe ich mir das EntityFramework installiert und ein Model von der Tabelle NavField09vs18 erstellt.

 

Die C# Anwendung kann hier auf GitHub eingesehen werden. Kurz erklärt:

- CreateSQL.cs -> Funktionen für die Script Generierung

- TableCompare.cs -> Funktionen für Tabellen und Felder Vergleich

- Settings.cs -> Datenbank und Sonstige EInstellung

- In der App.config befindet sich noch der Conn String zur Entity

 



Kommentare