[Gelöst] ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 09:08

Guten Morgen,

wir haben 2 Dynamics NAV 5.0 SP1 Update 2 Datenbanken. Eine ist eine native Datenbank, die andere ist eine SQL-Datenbank.
Von der SQL-Datenbank greifen wir mit ODBC auf die native Datenbank zu und übertragen Daten einer Tabelle.
Dazu wurde der Dynamics NAV 5.0 SP1 ODBC Treiber installiert und entsprechend konfiguriert.

Die Übertragung der Daten von einer Datenbank/Tabelle zur anderen Datenbank/Tabelle funktioniert einwandfrei für alle Felder ausser Zeitfelder (DataType TIME).
Bei Zeitfeldern wird immer das heutige Datum als Wert zurück gegeben. Das ist natürlich falsch und funktioniert nur bis zum 23. eines Monats ... dann knallt es wegen ungültigen Zeitwerten.

Ich begreife aber nicht, wieso dies z.B. bei Datumsfeldern (DataType DATE) einwandfrei funktioniert (mit korrekten Werten) und bei Zeitfeldern (DataType TIME) nicht funktioniert.
Hier ein Code-Beispiel, wie die Daten gelesen und übertragen werden:

Code:
ADOConn.Open(ConnStr);
CREATE(ADOrs);
ADOrs.Open('SELECT * FROM ' + SourceTableName, ADOConn, OpenMethod, LockMethod);
IF NOT ADOrs.EOF THEN
BEGIN
  ADOrs.MoveFirst;
  REPEAT
    RecRef.OPEN(TargetTableNo);
    FOR i := 1 TO RecRef.FIELDCOUNT DO BEGIN
      FldRef := RecRef.FIELDINDEX(i);
      Fieldname := CONVERTSTR(FldRef.CAPTION, '.', '_');   // Replace . with _
      CASE FORMAT(FldRef.TYPE) OF

        // Boolean Values
        'Boolean': BEGIN
          FldRef.VALUE := ADOrs.Fields.Item(Fieldname).Value;
        END;

        // Date Values
        'Date': BEGIN
          EVALUATE(DateTemp, FORMAT(ADOrs.Fields.Item(Fieldname).Value));
          FldRef.VALUE := DateTemp;
        END;

        // Time Values
        'Time': BEGIN
          EVALUATE(TimeTemp, FORMAT(ADOrs.Fields.Item(Fieldname).Value));
          FldRef.VALUE := TimeTemp;
        END;

        // Option Values
        'Option': BEGIN
          IntTemp := TextToOptionValue(FORMAT(ADOrs.Fields.Item(Fieldname).Value),
                                       FldRef.OPTIONCAPTION);
          FldRef.VALUE := IntTemp;
        END;

        ELSE BEGIN
          IF FORMAT(ADOrs.Fields.Item(Fieldname).ActualSize) <> FORMAT(0) THEN
            FldRef.VALUE := FORMAT(ADOrs.Fields.Item(Fieldname).Value);
        END;

      END;
    END;


Ich habe auch schon versucht, den erhaltenen Wert in ein Text-Feld zu übertragen. Aber auch dort erhalte ich immer das heutige Datum als Zeitwert!?!

Habt ihr eine Idee, wieso ich immer das heutige Datum erhalte?
In der gelesenen Tabelle sind immer Zeitwerte im entsprechenden Feld vorhanden.
Und es funktioniert mit allen Feld DataTypes, ausser mit dem DataType TIME.

Momentan bin ich ratlos.

Vielen Dank, Beno
Zuletzt geändert von beno am 28. Februar 2013 16:04, insgesamt 1-mal geändert.

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 10:06

Was steht denn in FORMAT(ADOrs.Fields.Item(Fieldname).Value) drin?

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 10:23

Im SQL Server werden NAV-Date und -Time Felder als DATETIME abgespeichert. Daher funktioniert Date ohne Probleme aber Time nicht.

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 10:31

Versuche doch mal, dein ADOrs.Fields.Item(Fieldname).Value in eine DateTime-Variable zu übertragen, und dann mittels DT2Date bzw. DT2Time den jeweiligen Wert in dein Datums- bzw. Time-Feld zu übertragen.

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 10:38

Ich habe den Wert (Feld "Änderungszeit") absichtlich mal in eine Textvariable (1024 Stellen lang) empfangen.
Der Wert war gestern 27.02.13, heute ist es 28.02.13. Es wird also immer das Tagesdatum (TODAY) übertragen.
Beim Feld "Änderungsdatum" kommt aber immer das tatsächlich vorhandene Datum rüber (also z.B. 17.08.99).

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 10:39

Danke für den Hinweis. Ich werde nun mal versuchen, den ADOrs.Fields.Item(Fieldname).Value in eine DateTime-Variable zu übertragen.
Ich melde mich wieder.

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 10:48

Ich hätte den Wert '01-01-1753' erwartet, da dieser Wert für jedes Time-Feld enthält. Ich bin gespannt, ob die richtigen Zeiten ankommen oder immer eine Stunde versetzt sind. Kannst du das bestätigen?

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 11:05

Nein, das kann ich nicht bestätigen. Ich erhalte folgende Werte zurück:

Textvariable (Länge 2024)
TxtTEST := FORMAT(ADOrs.Fields.Item(Fieldname).Value);
Resultat = 28.02.13

DateTime Variable
EVALUATE(DateTimeTEST, FORMAT(ADOrs.Fields.Item(Fieldname).Value));
Resultat = 28.02.13 00:00

Der Datensatz hat aber ein Änderungdatum = 07.12.09 und eine Änderungszeit = 07:24:40.
Das Datum kommt korrekt rüber, die Zeit wie oben beschrieben.

Die Ursprungsdatenbank ist native, die Zieldatenbank ist SQL.

Ab Morgen Freitag (01.03.13) wird der Prozess wieder ohne Fehler laufen. Nur habe ich dann eine Änderungszeit von 01:03:13 in jedem Datensatz...

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 11:11

Du hast das Time-Feld genommen oder das Date-Feld? Es sieht so aus als ob Du das Date-Feld genommen hast und nicht das Time-Feld.

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 11:20

Der Fieldname ist "Änderungszeit", der Wert des Feldes "FldRefType" ist "Time".
Vom Index (Feldzähler) trifft es auch zu. Es ist das letzte Feld im Datensatz.
Es muss sich um die Zeit handeln.

Re: ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 12:00

beno hat geschrieben:Die Ursprungsdatenbank ist native, die Zieldatenbank ist SQL.


Oh, ich bin vom Gegenteil ausgegangen. Ich dachte ihr würdet die Daten vom SQL-Server in die native Datenbank bringen.

ODBC Problem mit Zeitfeld (Rückgabewert = Datum)

28. Februar 2013 16:03

Soooooooo... endlich eine Lösung gefunden. Und erst noch wegen mehreren Foren-Einträgen in MSDynamics.DE!!!
Zeitfelder kann ich so wie ursprünglich realisiert nicht übernehmen. In allen von mir durchgeführten Fällen erhielt ich immer nur das Tagesdatum und nicht den Zeitwert.

Ich musste Folgendes für Zeitfelder realisieren:

Für Zeitwerte rufe ich eine neue Funktion "TextToTime" auf:
Code:
        // Time Values
        'Time': BEGIN
          EVALUATE(TimeTemp,COPYSTR(TextToTime(Fieldname),12,8));
          FldRef.VALUE := TimeTemp;
        END;


In dieser Funktion "TextToTime" muss ich den Wert als Stream verarbeiten und zurückgeben:
Code:

TextToTime(FieldnameL : Text[200]) FieldValueL : Text[30]
IF ISCLEAR(ADOStream) THEN
  CREATE(ADOStream);
ADOStream.Open;
ADOStream.WriteText(ADOrs.Fields.Item(FieldnameL).Value);
ADOStream.Position := 0;
FieldValueL := FORMAT(ADOStream.ReadText);
ADOStream.Close;
CLEAR(ADOStream);
EXIT(FieldValueL);


So erhalte ich nun einen TimeStamp zurück: "28.02.2013 07:54:08"
Die ersten 10 Stellen enthalten immer das Tagesdatum plus 2 Leerstellen.
Die letzten 8 Stellen entsprechen dann dem Wert des Zeitfeldes.

Ohne diesen Umweg habe ich mit allen von mir versuchten Varianten immer nur die ersten 10 Stellen, also das Tagesdatum, erhalten.

Vielen Dank für Eure Unterstützung.
Beno