[gelöst] Berechnung auslagern oder intern durchführen?

14. Juni 2012 09:28

In einer Tabelle werden anhand diversen Datumsfeldern und anderen Informationen der Status eines Eintrags (aktiv/abgelaufen) berechnet. Dazu habe ich eine Funktion erstellt, die per onModify bzw. onInsert aufgerufen wird. Soweit so gut, allerdings benötige ich den Status tagesaktuell - also müssen die Zeilen täglich neu berechnet werden.

Welche Möglichkeiten bietet mir NAV mit Bordmitteln hierzu an? (mal abgesehen von der Möglichkeit, die Daten bei jedem Aufruf über die Form neu berechnen zu lassen - scheidet wegen der Menge aus).

Alternativ fallen mir externe Lösungen ein:
-Auslagern der Funktion in eine Codeunit und triggern über Webservice (z.B. Cronjob)
-SQL Agent Job (allerdings muss ich dazu die Funktion nach SQL übertragen..)

Vielen Dank schon mal für eure Tipps!
Zuletzt geändert von JoergR am 14. Juni 2012 17:15, insgesamt 1-mal geändert.

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 09:38

Objektaufrufplaner, Application-Server?

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 10:25

Status eines Eintrags (aktiv/abgelaufen)


Musst du auf diesen Wert filtern können, oder reicht dir die Information?

Nach eigener Erfahrung mit der Aktualisierung des aktuellen VK- Preises in die Artikelkarte, kann ich von solchen CRON- Jobs nur abraten. Erst nachdem wir das ganze jetzt auf eine Funktion umgestellt haben, die den VK-Preis aktuell zur Laufzeit berechnet, läuft es stabil. Ursache für Probleme waren die Änderung der Daten unter Tage, was man nur durch eine Unmenge an Triggern in den Begriff bekommen könnte, wobei man garantiert einige vergisst. Leider kann man auf diesen Wert nicht filtern, deshalb meine Frage.
Gleichzeitig ist das mein Vorschlag zur Lösung: Erstelle eine Funktion, die als Ergebnis deinen Status hat.

Gruß, Fiddi

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 10:30

Man muss leider darauf filtern können, da nur aktive angezeigt werden sollen.

Ich versuchs jetzt erstmal über einen SQL Agent Job.

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 10:41

Wie viele Datensätze sind es, und wie oft wird darauf zugegriffen?

Mir schwebt eine Neuberechnung beim öffnen des Forms/Page vor. Dabei könnte man evtl durch geschicktes Filtern, die Anzahl der Datensätze einschränken, die dabei neu berechnet werden müssen z.B. SETRANGE(Abgelaufen,false);

Gruß, Fiddi

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 10:45

Ist pro Mandant unterschiedlich, z.b. ~35000

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 10:52

Ist pro Mandant unterschiedlich, z.b. ~35000


auch gefiltert so viele?

Gruß, Fiddi

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 11:16

dann sind es durchaus ca. 50% weniger, aber das ist immer noch zu viel ...die Tabelle wird ja ständig von mehreren Mitarbeitern genutzt.

Hier mal mein Ansatz üer TSQL Script, falls es jemand interessiert

Code:
USE EntwicklungD
go

/*
 * Bestimmen der Vertragssituation zum korrigieren des Vertragsstatus in der Service Contract Line
 *
 * Vertragssituation ist ein Optionfeld in NAV!
 * 0 = leer
 * 1 = Aktiv
 * 2 = Inaktiv
 * 3 = noch nicht aktiv
 *
*/

begin transaction

/* Mandant ZN1 */

;with recordset_aktive as (
select
scl."Contract No_" as VertragsNr
from
"01$Service Contract Header" sch
left outer join "01$Service Contract Line" scl   on scl."Contract No_" = sch."Contract No_"
where
sch."Contract Type" = 1
and
sch.Status > 0
and
sch."Vertragsbeginn" <= GETDATE()
and
(sch."Expiration Date" > GETDATE() or sch."Expiration Date" is null or sch."Expiration Date" = '01.01.1753')
)
update  scl
   SET scl.Vertragssituation = 1 /* Status = Aktiv */
   from "01$Service Contract Line" scl
   right join recordset_aktive rs on (scl."Contract No_" = rs.VertragsNr)


;with recordset_nochnichtaktiv as (
select
scl."Contract No_" as VertragsNr
from
"01$Service Contract Header" sch
left outer join "01$Service Contract Line" scl   on scl."Contract No_" = sch."Contract No_"
where
sch."Contract Type" = 1
and
sch.Status > 0
and
sch."Vertragsbeginn" > GETDATE()
and
(sch."Expiration Date" > GETDATE() or sch."Expiration Date" is null or sch."Expiration Date" = '01.01.1753')
)
update  scl
   SET scl.Vertragssituation = 3 /* Status = noch nicht aktiv */
   from "01$Service Contract Line" scl
   right join recordset_nochnichtaktiv rs on (scl."Contract No_" = rs.VertragsNr)

usw usw..

commit transaction

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 11:35

Dann bau dir eine View, die du mit einer NAV.Tabelle verknüpfst.

Gruß, Fiddi

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 11:42

Hi Fiddi,
was würde mir der View hier bringen? Durch den View werden die Datensätze doch nur zur Anzeige"aufbereitet" oder irre ich gerade? Ich brauche die Daten physikalisch geändert da auch an anderen Stellen innerhalb NAV darauf zugegriffen wird.

gruß
Jörg

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 11:42

Datenbankprogrammierung sollte man wirklich als allerletztes Mittel benutzen. Schreiben von Daten in NAV Tabellen über SQL ist keine triviale Aufgabe.
Programmierungen ausserhalb von NAV reagieren nicht auf veränderte Programmierungen in NAV, wodurch bei einer späteren Anpassung der Trigger nicht berücksichtigt wird, und somit der Trigger evtl. ungültige Werte schreibt, die die Artikeltabelle unbrauchbar macht (bis die ungültigen Daten entfernt sind).

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 12:04

Da hast du natürlich Recht.

Mittlerweile bin ich auch schlauer was den Objektaufrufplaner betrifft...der wird bei uns nicht mehr als Client gestartet sondern läuft als Webservice und wird per Sql Agent gesteuert.
D.h. ich kann die Funktion einfach in die Codeunit des Webservice anhängen und fertig.

Naja gut a bisserl SQL übung schadet nie :)

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 14:35

was würde mir der View hier bringen? Durch den View werden die Datensätze doch nur zur Anzeige"aufbereitet" oder irre ich gerade? Ich brauche die Daten physikalisch geändert da auch an anderen Stellen innerhalb NAV darauf zugegriffen wird.


Die View könnte die Werte zur Laufzeit ermitteln, und du könntest trotzdem darauf Filtern.

EDIT: Evtl. würde es funktionieren, den Status in den Köpfen zu aktualisieren, und dann per Flowfield in die Zeilen zu spiegeln

Gruß, Fiddi

Re: Berechnung auslagern oder intern durchführen?

14. Juni 2012 17:14

Hallo,

danke für euere Hilfe, ich habs nun tatsächlich über den Objektaufrufplaner gelöst. Ist schon komfortabel wenn über SQL Agent gesteuert.

gruß
Jörg