Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

11. August 2018 12:46

Hallo Forum,

für meinen Arbeitgeber, eine Unternehmung bestehend aus ein paar mittleren Einzelfirmen, soll ich die erste der bestehenden Anwendungen in punkto Daten von NAV2009R2 auf NAV2018CU6 migrieren. Daten deshalb, da wir "auf der gründen Wiese" anfangen möchten, Events und Extensions nutzen möchten, um zukünftig die Updates fahren zu können. Alle bisherigen kundenspezifischen Funktionalitäten, deren Objekte und Felder in Standardtabellen sollen weg und die Themen neu aufgerollt werden. Dass einige der kundenspezifischen Tabellendaten und deren Daten in Feldern von Standardtabellen im Verlauf des "Neubeginns" wieder benötigt werden ist eingeplant.

Da wir auch unsere Fibu vollständig in NAV genutzt haben und nutzen, sollte eine Migration der Daten über die Migrationswege von MS stattfinden. Wir haben in den Haupt-Postentabellen jeweils nur 1 - 2 Infofelder, welche vernachlässigt werden können.

Das Modul "Zahlungsverkehr AR6.00" ist noch im Altsystem, die dazu Daten ebenfalls. Das wurde in der Vergangenheit durch OPPlus (7.x) abgelöst. OPPlus soll weiterhin mit der neusten Version genutzt werden.

Dimensionen wurden bisher nicht genutzt, dass wird im Zuge des Neubeginns manuell eingeführt.

Meine Aufgabe ist es nun, den Migrationsweg auszuarbeiten. Ich bin schon einige Jahre mit NAV als Entwickler unterwegs, habe einen solchen Vorgang jedoch noch nicht gemacht:

- Alle Standardtabellen und Standardfelder sollen von NAV2009 in NAV2018CU06 migriert werden.
- Es soll keinerlei kundenspezifische Programmierung und keine deren Einträge im DocumentationTrigger übernommen werden.
- Die kundenspezifischen Anforderungen werden basierend auf den Vorgaben von MS und deren dazugehörende technische Neuerungen vollständig neu ausgearbeitet und entsprechend implementiert.
- Die zu dieser Neuimplementierung im Altsystem vorhandenen Daten werden "JustInTime" voraussichtlich über RapidStart dem so neu entstandenen Datenschema hinzugefügt. Die entsprechenden Referezierungen dazu befinden sich im Altsystem.

Ich muss auch berücksichten, dass ich diesen Migrationsvorgang wiederholen muss - Stichwort "Zeitaufwand vor Echtstart".

Meine Frage ist: Wie würdet Ihr in diesem Fall vorgehen, um im Ergebnis nur die Daten für die STandardfelder in den NAV2018 - Standard migriert zu bekommen?

Grüße
Achim

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

14. August 2018 13:51

Hallo Achim,

ich würde dies in 2 Steps durchführen. Einmal von 2009 auf 2013 und dann von 2013 auf 2018.

https://docs.microsoft.com/en-us/dynamics-nav/upgrading-to-microsoft-dynamics-nav-2017 Hier steht auch noch mal beschrieben wie das von 2009 aussehen kann.

Also am besten wäre es wenn du zuerst auf 2013 konvertierst, dann die Objekte von 2013 importierst und dann das UpgradeToolkit für Upgrade601700.2.fob importierst und ausführst.
Danach auf 2018 anheben dann das Toolkit Upgrade7001100.fob importieren. Sync NAV-Tenant ausführen und dann die Daten upgraden. So in der Kurzfassung würde ich es machen.

Grüße
slgeorg

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

14. August 2018 14:22

Hallo,

hier gab es eine längere Diskussion zu dem Thema.

Gruß Fiddi

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

14. August 2018 14:26

Außerdem beachten, dass bei NAV 2018 CU2 ein "Zwischenstopp" erforderlich ist:
Best Practices Tips and Tricks for Upgrading Part 4 'No, we did not forget the toolkit'

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

14. August 2018 14:32

Hallo,
Außerdem beachten, dass bei NAV 2018 CU2 ein "Zwischenstopp" erforderlich ist:


sicher? im aktuellen Build ist wieder ein komplettes Upgradetoolkit enthalten.

Gruß Fiddi

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

14. August 2018 14:50

Fiddi hat geschrieben:sicher?

Falls die Doku auf dem aktuellen Stand ist, ist das weiterhin so und alles andere zwar ggf. möglich, aber "not supported".
https://docs.microsoft.com/en-us/dynami ... namics-nav

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

14. August 2018 17:34

Also wir hatten vor ein paar Wochen eine Migration von einer ganz alten NAV 5.0 Datenbank (Runtime 2009 R2) mit unglaublich vielen Individualanpassungen auf eine "nackte" NAV 2018 CU05 Version mit OPplus.

Die Schritte waren (ganz grob skizziert):
  1. Leeren aller Individual-, Branchen- und AddOn-Felder (außer OPplus) in NAV-Standard-Tabellen
  2. Vorbereiten eines NAV 2009 R2 Objektstands (z. B. Vergrößerung der Felder [Text30 -> Text50], ... nachbilden
  3. Diesen angepassten Objektstand in die zu migrierende Datenbank importieren.
  4. Upgrade mittels Microsoft Toolkit von 2009 R2 auf 2013 RTM
  5. Upgrade mittels Microsoft Toolkit von 2013 RTM auf 2015
  6. Upgrade mittels Microsoft Toolkit von 2015 auf 2018 CU05 inkl. OPplus
Einen Zwischenstop über 2018 CU02 gab es ebensowenig wie Zwischenschritte über 2016 oder 2017.

Irgendwo dazwischen fand dann noch das Upgrade von OPplus auf die in 2018 verwendete Version statt.
Wann und wie das Upgrade von OPplus durchgeführt wird, ist von der alten sowie der neuen OPP-Version sowie den von OPP genutzten Modulen abhängig.
Kommt ihr z. B. von einer ganz alten OPP-Version, die noch im 70.000er-Bereich liegt, dann sieht das Upgrade natürlich anders aus, als wenn ihr z. B. von OPP8.00 auf OPP11.00 upgraded.

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

14. August 2018 18:35

Hallo,

wenn du das mit einer kleineren Datenbank machst, das funktioniert der Weg über die einzelnen Upgrade- Toolkits.

Aber schon bei einer 100 GB- Datenbank kommst du mit dem Standard an Laufzeiten, die über ein Wochenende gehen.

Und das mit dem: "Wir brauchen keine Altdaten. Wir wollen nur Standard.,..." höre ich laufend. Meistens dauert es keine zwei Monate bis dann wieder etwas gebastelt wird.

Die Ursache dafür ist, dass derjenige, der diese Aussage(n) trifft, meistens gar nicht (mehr) weiß, was der Standard eigentlich ist :roll: .

Außerdem wird nicht bedacht, dass man für Auswertungen und Vergleiche Altdaten benötigt, die dann weg sind.

Daher meine Vorgehensweise:
1. Man hole sich den Inhalt der Tabelle "Field" (geht im NAV2009 CC über eine From- preview) in ein Excel- und/oder Text-file und vergleiche das ganze mit einer unangepassten NAV2009- Version (hier evtl. mit Opplus).
2. Für jedes der unterschiedlichen Felder (also die Felder die nur in der eigenen Version sind, oder eine andere Feldlänge haben) prüft man Sinn und Nutzen und prüft ob Inhalt vorhanden ist. Wenn man das Feld nicht zuordnen kann, wenn es leer ist oder Unsinn drin steht, weg damit. Bei einer Größenänderung vom z.B. Beschreibungstext des Artikels oder Belegs auf einen Wert der größer ist als in der Ziel- Version, musst du dir schon etwas einfallen lassen.

Auf diese Weise findest du heraus, ob du wirklich ohne deine Sonderfelder auskommst. Wenn du die Felder entsorgt hast, dann folgt ein "Compile All" (natürlich in einer Testdatenbank), der deinen Code bereinigen. Und damit den Merge vereinfachen wird. Durch den Vergleich des Codes mit der Basisversion findest du dann deine Baustellen heraus.

Die kundenspezifischen Anforderungen werden basierend auf den Vorgaben von MS und deren dazugehörende technische Neuerungen vollständig neu ausgearbeitet und entsprechend implementiert

Das solltest du ganz genau prüfen, ob das überhaupt über Extensions/Events funktioniert.
Nicht alles was bisher möglich war funktioniert mit Extensions/Events. Gerade wenn du mehrere Module von Fremdanbietern hast, die sich miteinander unterhalten müssen, kann es da zu Problemen kommen. Schon das vergrößern eines bestehenden oder das hinzufügen eines zusätzlichen Feldes oder ein auskommentierter TESTFIELD kann hier zum Killer werden.

Daher Vorgehensweise:
1. Analyse: Was hab ich eigentlich (besonderes), Was brauch ich davon noch (und das detailliert, nicht nur pauschal)
2. Aufräumen: Alles beseitigen was mit dem nicht mehr benötigten Feldern/Objekten zu tun hat. Das können auch Daten aus irgendwelchen Log- Tabellen sein (im CC2009 unter Datei/Datenbank/Infomationen/Tabellen prüfen)
3. Merge: Übernahme der Programmierung in die neue Version, entweder durch Text-Merge (das funktioniert sogar von Forms in Pages) oder sinngemäße Programmierung in neuen Objekten
4. UpgradeToolkit: Erstellen einer Upgradetoolkiterweiterung, die die zu übernehmenden Felder konvertiert. Dabei beachten, die nicht benötigten Felder zu leeren.
5. Upgrade testen: Prüfen ob das Update funktioniert. Falls nicht bei Punkt 3 oder 4 wieder einsteigen.

Das ganze natürlich nicht sofort in der Echt- Datenbank.

Je nach Größe der Datenbank kann es allerdings sinnvoll sein Punkt 2. schon vor dem Update in der Echtdatenbank zu durchzuführen. Das spart beim Update Zeit und man hat die Chance zu prüfen ob die fehlenden Daten und Objekte wirklich überflüssig waren. 8-)

Gruß Fiddi

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

15. August 2018 08:42

Bei der Dauer einer Migration muss ich fiddi Recht geben.
Die Datenbank unserer 5.0 -> 2018 Migration hatte zum Schluss eine Größe von ca. 32 GB und dauerte schon einen ganzen Arbeitstag.
Für eine Datenbank, die schon seit 9 Jahren im Echtbetrieb ist und drei Mandanten enthält, ist das absolut nichts. Das liegt aber auch nur daran, dass es reine FiBu-Mandanten waren, die sonst rein gar nichts in der Datenbank gemacht hatten.
Zum Vergleich:
In unserer alten 5er Datenbank sind (bis auf die drei "herausmigrierten") noch alle anderen 19 Mandanten vorhanden.
Die Datenbank ist 626 GB groß.
Die migriert man nicht "mal eben", da reicht auch kein normales Wochenende.

Für die Migration sollte man auch den leistungsstärksten Server nutzen, den man auftreiben kann.
Darüber hinaus ist es sinnvoll, wenn NAV-Client, ServiceTier und SQL-Server für die Migration auf demselben Server laufen, und man sich per RDP o. ä. daraufschaltet, damit die Daten nicht permanent über das Netzwerk geschaufelt werden müssen.

Dass man vor der Echtmigration mindestens eine Testmigration durchführen sollte dürfte wohl eine Selbstverständlichkeit sein, denn anschließend muss man ausgiebig testen, ob die Qualität der Daten gewährleistet ist und alle Geschäftsprozesse noch ordnungsgemäß funktionieren.
Mir ist noch keine einzige Migration begegnet, bei der die Testmigration direkt im ersten Anlauf ganz ohne irgendwelche Komplikationen durchgelaufen wäre.
Irgendein Feld hat man immer vergessen, sei es, dass es fehlt oder dass es nicht auf die tatsächlich genutzte Länge vergrößert wurde.

Und damit man ein Gefühl für die Dauer der Migration bekommt, sollte man jeden einzelnen Schritt in einer Excel-Tabelle mit Startzeitpunkt, Endezeitpunkt und Dauer [Minuten] protokollieren.
Manche Schritte macht man einmal, andere jedoch je Mandant. Auch das sollte in der Excel-Tabelle berücksichtigt werden.
Anhand dieser Tabelle kann man dann die ungefähre Laufzeit für die Migration abschätzen und ein geeignetes Zeitfenster für die Echtmigration ermitteln. (Wochenende, langes Wochenende, Betriebsferien)

Ich hatte schon Migrationen, da gab es leider nur normale Wochenenden, die in Frage kamen, und so mussten wir von Freitag Nachmittag bis Montag Morgen rund um die Uhr im Schichtbetrieb die Migration durchführen.
Anhand der Excel-Tabelle konnten wir die Schichten hervorragend einplanen, so dass jeder Beteiligte relativ genau wusste, wann er an der Reihe ist. Da klingelte dann halt in der Nacht von Samstag auf Sonntag morgens um 2:30 Uhr das Handy, und der Kollege kündigte an, dass man jetzt noch ca. 30 Minuten hat, um in Ruhe einen Kaffee zum wachwerden zu trinken, da man dann übernehmen darf.

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

15. August 2018 17:43

Hallo,

man schafft eine 100 GB SQL-DB NAV 4.0 mit einem Mandanten ohne Dimensionen (aber auch das ist angepasst vertretbar machbar) mit angepasstem Update, (d.h. Step1 in NAV4, technisch NAV2013, NAV2015, NAV- Upgrade in NAV2015, und teilweise Konvertierung mit SQL-Skript) in ca. 7 Stunden auf einer gut ausgestatteten Blechkiste ohne SSDs.

Das hat außerdem den Vorteil, das man nur die Daten in NAV4 sichern, und in NAV2015 wieder rekonstruieren musste, sich also das Merge in NAV 2013 gespart hat. Beim Umstieg auf NAV2018 käme da dann noch ein Merge auf NAV2015 dazu.
Der Programmieraufwand wäre dann fast genauso hoch, wie die Anpassung der Upgrade- Routinen in NAV4 und NAV2015/2018 und das schreiben des SQL-Skripts.

Gruß Fiddi

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

17. August 2018 00:38

Hallo Ihr Hilfbereiten,

Eure Antworten haben mir sehr weitergeholfen, so dass ich gleich losgelegt habe. Hier grob skizziert:

1. NAV2009R2 CC -> SQL konvertiert
2. alle customized Felder und die AddOn-Felder in Standardtabellen (außer OPPlus) geleert.
3. NAV2009R2 Standardobjekte und OPPlus-Objekte eingespielt
4. UpgradeToolkit ausgeführt
Ergebnis: Nur noch die Tabellen sind vorhanden - nicht kompiliert
5. Konvertierung auf NAV2013R1 durchgeführt
6. Konvertierung auf NAV2013R2 durchgeführt
7. NAV2013R2 Objekte und OPPlus-Objekte in einer Standard-DB zusammengebracht

Dieses Objektpaket wollte ich in die konvertierte NAV2013R2 einspielen, jedoch bekomme ich beigefügte Fehlermeldung. Den SQL-Benutzer habe ich entsprechend eingerichtet. Ich habe jetzt alles mir erdenkliche geprüft, mir fällt nichts mehr ein, woran es liegen könnte. Im Ereignisprotokoll steht nichts drin. Die NAV2013 DevUmgebung hat Verbindung zur Datenbank.

Habt Ihr eine Idee?

Grüße
Achim
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

17. August 2018 07:18

Ab NAV 2013 R2 ist man in der neuen Welt der Schemaverwaltung.
Funktioniert Sync-NAVTenant grundsätzlich mit dem Dienst?

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

17. August 2018 13:20

Ich teste momentan folgendes Verfahren für eine Datenübernahme aus 2009CCR2 SQL auf Nav2018:

Habe mir eine Anwendung geschrieben welche mir die Tabellen und Felder 2009 vs 2018 vergleicht und ein T-SQL Script generiert.
Das Script überträgt die Daten vom 2009 in die passenden 2018er DB Tabellen. Dauert keine 5 Minuten für die 120 GB DB.

Dann habe ich mir mit Rapid Start Services in einer Blanko Paket zusammengestrickt ohne Daten.
Das lese ich nach der SQL Datenübernahme ein, und exportiere die Daten, und lese es in einen Blanko Mandant wieder neu ein, so habe ich dann die ganzen Felder/Tabellen Prüfungen/Validierungen, und Fehler ...

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

17. August 2018 13:21

Hallo Kai,

die PowerShell sagt, dass es dort kein CMLet "Sync-Tenant" gäbe. Ich scheine auf dem Schlauch zu stehen.

Grüße
Achim

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

17. August 2018 13:37

AchimMueller hat geschrieben:die PowerShell sagt, dass es dort kein CMLet "Sync-Tenant" gäbe. Ich scheine auf dem Schlauch zu stehen.

Dann fehlt noch das NavAdminTool-Modul.
Abhilfe siehe hier. Bei NAV 2013 R2 dann im 71er-Pfad.

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

17. August 2018 13:39

Du hast auch die "Dynamics NAV XXXX Administration Shell" benutzt?

@elTorito:

Magst du dein Skript veröffentlichen?

Gruß Fiddi

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

17. August 2018 15:05

fiddi hat geschrieben:Du hast auch die "Dynamics NAV XXXX Administration Shell" benutzt?
@elTorito:
Magst du dein Skript veröffentlichen?
Gruß Fiddi


Hmm. Ja, kann ich mal versuchen. Ist alles recht quick & dirty :)
Ich versuch mal die Schritte aufzulisten, Script/e kann ich ja noch nachreichen:

- Hab mir eine Excel Tabelle mit 2 Arbeitsblättern erstellt (NAV2009,NAV2018), dann in NAV2009 und NAV2018 die Tabellen/Felder Relationen geholt. (Form/Page auf Tabelle Field).
- Dann auf SQL eine DB erstellt, wo ich 2 Tabellen NAV2009,NAV2018 angelegt habe,dort jeweils die die Excel Sheets importiert.
- Eine weitere Tabelle NavFields09vs18 angelegt und dies gefüllt mit Werten aus NAV2009/NAV2018:
- Ein SQL Verbindungsserver zum TestNAV2009 erstellt

Code:
-- Übernimmt alle Felder aus Tabelle NAV2018
INSERT INTO NavFields09vs18 (TableNo,TableName2018,FieldNo,FieldName2018 ,FieldNeededIn2018, Type2018, Class2018, Enabled2018)
SELECT TableNo,TableName,No,FieldName, 0, Type, Class, Enabled FROM NAV2018$
-- 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 FieldName2009ChangedIn2018 =  CASE 
                        WHEN FieldName2018 <> FieldName2009 THEN 1
                        ELSE 0
                    END
UPDATE NavFields09vs18 
SET TableChangedNameIn2018 =  CASE 
                        WHEN TableName2018 <> TableName2009 THEN 1
                        ELSE 0
                    END

UPDATE NavFields09vs18 
SET TableDeletedIn2018 = CASE 
                        WHEN NOT EXISTS (SELECT 1 FROM NAV2018$ WHERE TableNo = [NAV2018$].[TableNo]) THEN 1
                        ELSE 0
                    END

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

SELECT *
  FROM [DemoDB].[dbo].[NavFields09vs18] ORDER by TableNo, FieldNo ASC


In C# mit EntityFramework frage ich die NAVFields09vs18 ab:

Code:
 static void CreateTSQLScripts()
        {
            using (var db = new DemoDBEntities())
            {
                IEnumerable<int> mytables = new int[] {};
                mytables = new int[] { 9};

                // Display all affected tables
                var affectedTables = from navfields in db.NavFields09vs18
                                     where (mytables.Contains(navfields.TableNo))
                                     group navfields.TableNo by navfields.TableNo into tablegroup
                                     orderby tablegroup.Key ascending
                                     select tablegroup.Key;
                foreach (var tno in affectedTables)
                {
                    System.Diagnostics.Debug.WriteLine("--Create TSQL for TableNo " + tno);
                    CreateTSql.CreateSqlScript(tno);
                }
            }
        }


Naja, und CreateSQL ist der schmutzigste Teil, wo ich je nach Fehlermeldung "interagiert" habe, also das T-SQL Script dahin anpassen dass es in 2018 den richtigen Feldname anspricht, falls er anders als in 2009 heißt, Default werte setzen, weil in 2018 ja fast alles NOT NULL ist, flowfields ignorieren, Datentypen abfragen. Bin da bisher via Try and Error vorgegangen

Code:
public static void CreateSqlScript(int tableNo)
        {
            using (var db = new DemoDBEntities())
            {
                // Display all Data from the database
                var query = from b in db.NavFields09vs18
                            where (b.TableNo == tableNo && b.Class2018 != "FlowField" && b.Class2018 != "FlowFilter" && b.Enabled2018 == "Ja")
                            orderby b.TableNo, b.FieldNo
                            select b
                            ;
                string Columns2018 = "";
                string TableName = "";
                //System.Diagnostics.Debug.WriteLine("All Columns in the Table:");
                foreach (var item in query)
                {
                    Columns2018 = Columns2018 + '[' + DataClass.ReplaceChar(item.FieldName2018) + ']' + ',';
                    TableName = DataClass.ReplaceChar(item.TableName2018);
                }
                Columns2018 = Columns2018.Remove(Columns2018.Length - 1);
                string sqlcmd = "";
                string sqlcmddelete = "";
                if (Settings.WithDeleteStatements == true)
                {
                    sqlcmddelete = sqlcmddelete + "DELETE FROM [NAVDB_110].[dbo].[" + Settings.TargetCompany + "$" + TableName + "]";
                }
                sqlcmd = sqlcmd + "INSERT INTO [NAVDB_110].[dbo].[" + Settings.TargetCompany + "$" + TableName + "] (";

                sqlcmd = sqlcmd + Columns2018 + ") ";

                DataTable dt18 = DataClass.GetSQLTableSchema(Settings.ConnStringPFGNWOOD18, "[NAVDB_110].[dbo].["+ Settings.TargetCompany + "$" + TableName + "]");
                DataTable dt09 = DataClass.GetSQLTableSchema(Settings.ConnStringPFGNWOOD09, "[NAVDB_TEST].[dbo].["+ Settings.SourceCompany + "$" + TableName + "]");



                sqlcmd = sqlcmd + " SELECT ";
                if (Settings.SelectNRowsToInsert > 0)
                {
                    sqlcmd = sqlcmd + " TOP (" + Settings.SelectNRowsToInsert.ToString()+") " ;
                }
                string Columns2009 = "";
                foreach (var item in query)
                {
                    if (item.FieldName2009 != null)
                    {
                        if (item.FieldName2009ChangedIn2018 == true)
                        {
                            //System.Diagnostics.Debug.WriteLine("FNo: "+ item.FieldNo +" Field2009: " + item.FieldName2009 + " F18: " + item.FieldName2018 + " Type" + item.Type2018);
                            Columns2009 = Columns2009 + CompareTableFields.GetFieldTypeIn2018(TableName, DataClass.ReplaceCharPoint(item.FieldName2018)) +",";
                        } else  if (CheckTypeIn2009Equivalent(item.FieldName2009,dt09) != "")
                        {
                            Columns2009 = Columns2009 +  CheckTypeIn2009Equivalent(item.FieldName2009, dt09) + ',';
                        }
                        else {
                            Columns2009 = Columns2009 + '[' + DataClass.ReplaceCharPoint(item.FieldName2009) + ']' + ',';
                        }
                    }
                    else
                    {
                        //System.Diagnostics.Debug.WriteLine("FNo: " + item.FieldNo + " Field2009: " + item.FieldName2009 + " F18: " + item.FieldName2018 + " Type" + item.Type2018);
                        switch (item.Type2018)
                        {
                            case "GUID":
                                Columns2009 = Columns2009 + "NEWID() ,";
                                break;
                            case "Media":
                                Columns2009 = Columns2009 + "NEWID() ,";
                                break;
                            case "DateTime":
                                Columns2009 = Columns2009 + "SYSDATETIME() ,";
                                break;
                            case "Decimal":
                                Columns2009 = Columns2009 + "0 ,";
                                break;
                            case "RecordID":
                                Columns2009 = Columns2009 + "cast('' as varbinary(50)) ,";
                                break;
                            default:
                                Columns2009 = Columns2009 + " '',";
                                break;
                        }
                    }
                }
                if (Columns2009.EndsWith(","))
                    Columns2009 = Columns2009.Remove(Columns2009.Length - 1);

                sqlcmd = sqlcmd + Columns2009+" ";

                sqlcmd = sqlcmd + " FROM [SQLTEST].[NAVDB_TEST].[dbo].[" + Settings.SourceCompany + "$" + TableName + "] t1 ";

                string strKeyFields = "";
                string strIdentityON = "";
                string strIdentityOFF = "";
                foreach (DataRow field in dt18.Rows)
                {
                    foreach (DataColumn property in dt18.Columns)
                    {
                        if (property.ColumnName == "IsKey")
                        {
                            if (field[property].ToString() == "True")
                            {
                                strKeyFields = strKeyFields + "[" + field[0] + "],";
                                //System.Diagnostics.Debug.WriteLine(field[0] + " " + property.ColumnName + " " + field[property].ToString());
                            }
                        }
                        if (property.ColumnName == "IsIdentity")
                        {
                            //System.Diagnostics.Debug.WriteLine(field[0] + " " + property.ColumnName + " " + field[property].ToString());
                            if (field[property].ToString() == "True")
                            {
                                strIdentityON =  "SET IDENTITY_INSERT [NAVDB_110].[dbo].[" + Settings.TargetCompany + "$" + TableName + "] ON";
                                strIdentityOFF = "SET IDENTITY_INSERT [NAVDB_110].[dbo].[" + Settings.TargetCompany + "$" + TableName + "] OFF";
                            }
                        }
                    }
                }

                if (strKeyFields.Count() > 1)
                    strKeyFields = strKeyFields.Remove(strKeyFields.Length - 1);
                string checkKeys = "";
                string[] s = strKeyFields.Split(',');
                foreach (string w in s)
                {
                    checkKeys = checkKeys + "t2." + w +"=t1."+w+" "+CheckFieldForCollate(w, TableName, dt18)+" AND ";
                }
                checkKeys = checkKeys.Remove(checkKeys.Length - 4);

                sqlcmd = sqlcmd + " WHERE NOT EXISTS(SELECT "+ strKeyFields + " FROM [NAVDB_110].[dbo].[" + Settings.TargetCompany + "$" + TableName + "] t2 WHERE "+checkKeys+")";

                foreach (DataRow field in dt09.Rows)
                {
                    //System.Diagnostics.Debug.WriteLine(field[0]);
                    //sqlcmd = sqlcmd + "["+ DataClass.ReplaceChar(field[0].ToString())+"],";
                }


                if (TableName == "Payment Terms") { }
                if (TableName == "Country_Region"){//Besondere behandlung notwendig?}
               
                System.Diagnostics.Debug.WriteLine(sqlcmddelete);
                if (strIdentityOFF != "")
                {
                    System.Diagnostics.Debug.WriteLine(strIdentityOFF);
                }
                System.Diagnostics.Debug.WriteLine(sqlcmd);
                if (strIdentityON != "")
                {
                    System.Diagnostics.Debug.WriteLine(strIdentityON);
                }
            }


KEINE GARANTIE dafür dass die Scripte das machen was sie sollten. Und kein Kommentar zum Code bitte :mrgreen:

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

28. August 2018 16:55

Hallo Gemeinde,

ich bin in punkto PowerShell und "Shells" noch etwas unerfahren gewesen und danke Euch für Eure Mithilfe.

Was im Zuge dieser Art des "Upgrades" wichtig ist ist die Vorgehensweise, wie Timo sie grob beschrieben hat. Danke auch an alle anderen Tippgeber.

Ich habe mir dazu eine eigene Codeunit entworfen, die alle Tabellen durchläuft - bis auf die Systemtabellen.
Die Codeunit besteht aus zwei Hauptschritten:

1. Schritt: Erstellen einer TXT-Datei, die neue Tabellen im 90000er Bereich neu anlegt, diese sind Puffertabellen. Die TXT-Datei wird manuell eingelesen und kompiliert
- Standardtabellen: Alle kundenspezifischen Felder der Standardtabellen + Primärschlüsselfelder werden als Puffertabelle neu angelegt. Sind Text/Code Standardfelder dabei, deren Länge vergrößert wurden, wurden diese als "Ausnahme" manuell im SourceCode hinzugefügt und werden ebenfalls zwischengespeichert.
- Kundenspezifisches: Diese Tabellen werden 1:1 als Puffertabellen angelegt
2. Schritt: Durchlaufen aller Datensätze dieser Tabellen und füllen der Puffertabellen im 90000er Bereich. Gleichzeitig werden die entsprechenden Felder der Standardtabellen geleert + Modify. Dieser Batch dauert zwar eine Weile, kann aber z.B. Nachts durchlaufen. Spätestens alle 100.000 Datensätze erfolgt ein Commit, sonst wird das mit der Zeit sehr langsam.

Dadurch kann ich in NAV2108 Upgrade-Codeunits während des Projektverlaufs erstellen und somit die Daten aus den Puffertabellen automatisiert an die Stellen schreiben lassen, die während der Entwicklungsphase des Projekts in Standardtabellen neu entstehen oder die in neue Tabellen mit geändertem Schema entstehen.

Da wir mit einer NAV2018 Standard-DB anfangen unser System neu aufzusetzen, in der nur noch OPPlus11 als Zusatz vorhanden ist (die Daten wurden mit den entsprechenden Toolkits upgegraded) ist dann das was Timo angab möglich: Alle Objekte ausser Tabellen löschen und bei jedem Upgrade-Schritt auf die Migrationsversion deren Standardobjekte "drüberwerfen" und vorher/hinterher die entsprechenden Toolkits von MS + OPPlus ausführen.

Die erste Datenbank die ich jetzt so updaten konnte ist nicht sehr groß. Gerade die Tabellen für die gebuchten Bereiche sind die Zeitfresser. Wenn man jedoch eine Steuerungstabelle mitführt kann man das so machen, dass der letzte gebuchte Posten/Beleg registriert werden kann und die Migrations-Codeunit ab dem zweiten RUN nur noch die Daten zwischenpuffert, die nach dem ersten RUN noch nicht im Puffer sind. Das kann man bis zum Echtstart wiederholen, so dass die Dauer der Umstellung vor Echtstart später nicht mehr so groß ist.

:-D

Vielen Dank an Alle!!

Grüße
Achim

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

28. August 2018 17:27

@ elTorito kannst du die Skripte evtl besser in deinem Github Account veröffentlichen und den Link schicken? Dann könnte man auch nachverfolgen ob es Bugfixes/Verbesserungen gab und zuarbeiten.

@AchimMueller
Wie hast du das Table generieren den gelöst ?

Ich bekomme es gerade nur hin einen schmutzigen Clone mit allen Tablerellations/Code und Keys zu erzeugen.
Im wesentlichen mache ich das selbe vom Ablauf her nur das ich noch Prüfungen eingebaut habe die mich vor Datenverlust schützen sollen.

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

29. August 2018 00:24

Hallo,

eine neue Tabelle als Textexport zu generieren, funktioniert am einfachsten mit einem Report, der über die Tabelle Field und "Compare Field" läuft. Wenn relevante Unterschiede in Vorhandensein und Größe von Feldern in einer Tabelle besteht, generierst du ein neues Objekt in einer Textdatei. Wie dieses Objekt aussehen muss, kannst du dir mit einer einfachen Tabelle, ohne Schnck Schnack (nur mit einer Variablen für jeden Typen, ohne Captions oder irgendetwas sonst). Diese Tabelle exportierst du als Text. Den Kopfteil, mit angepassten IDs und Namen, gibst du vor jeder neuen Tabelle aus. Die Felder sind ein Case- Stament, das nur eine Zeile in die Textdatei schreibt. Den Fuß aus der Textdatei gibst du nach jeder Tabelle aus.
Vorher solltest du noch den Primärschlüssel ermitteln und ebenfalls in die Textdatei schreiben.
Wenn du es ganz gut machen willst, dann schreibst parallel auch noch ein SQL-Skript, das die Daten kopiert oder löscht. Ein Muster für so ein SQL-Script, dass alle Mandanten bearbeiten kann, habe ich mal beigefügt.

Gruß Fiddi
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

31. August 2018 16:18

fiddi hat geschrieben:Du hast auch die "Dynamics NAV XXXX Administration Shell" benutzt?
@elTorito:
Magst du dein Skript veröffentlichen?
Gruß Fiddi


Hier Mein Beitrag zum Wochenende :-)
Habe hier mal meine ganze Vorgehensweise Quick & Dirty zusammengefasst,
Link zu Github auch dabei.


Falls im Code irgendwo noch Sensible Daten von mir auftauchen sollten, bitte ich um kurze Info.
Geht sicher auch dass man den Code ohne Sensible Daten hochlädt? Aber ich bin erst neu in GitHub, verwalte mein Code normalerweise auf visualstudio.com, weil da Private Projekte nichts kosten, und mein Code in der Regel nicht so schön ist :-)

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

1. September 2018 21:49

Optimal, thx @ elTorito

Es geht bei der kooperativen Entwicklung ja genau drum das auch mal 4 Augen drauf gucken und evtl. Vorschläge machen.
Außerdem bekommt man auf dem Link immer die neuste Version (Features/ Bugfixes) während der Source im Forum halt für immer so bleibt.

Was sensible Daten angeht verwende ich Parameter wie in diesem Skript. Dann bist du für einen Test gezwungen diese anzupassen, siehst im Git aber den Change und kannst diesen auch ausbauen/ nicht comitten.

Code:
$NavVersion = 100
$DatabaseName = "MyDataBase"
$WorkDir = "C:\Temp\Objects\"


https://github.com/Nody85/NavPowershell/blob/master/Proof_PartnerRelease.ps1

Re: Migration NAV2009R2 -> NAV2018CU06 ohne customized Dinge

26. November 2018 16:13

elTorito hat geschrieben:
fiddi hat geschrieben:Du hast auch die "Dynamics NAV XXXX Administration Shell" benutzt?
Hier Mein Beitrag zum Wochenende :-)


Hat sich jemand die Anleitung/Beschreibung gespeichert? ^^ :roll: :twisted:

PS: Falls es noch jemand braucht bitte an mich wenden.