none
Access 2003 vs MSSQL 2008 Datensatzherkunft bei Datum mit berechnetem Datum

    Frage

  • Hallo ich stelle gerade meine mdb auf mssql um

    da habe ich ein Problem bei einigen "Abfragen" wenn ich dort bei einem Datum eine "Berechnung" durchführe bekomme ich eine Fehlermeldung

    datetime2 ist inkompatibel mit tinyint (übrigens ist das datumsfeld in der mssql ein smaldate)

    die abfrage funktioniert so wie sie ist mit der mdb

    der fehler sitzt hier     (((tblAufkopf.MahnungsDatum)<=Date()-[TAGEzwischenMahnung])

    wenn ich (((tblAufkopf.MahnungsDatum)<=Date()-1) benutze geht es

    werte sind in [TAGEzwischenMahnung] da

    SELECT DISTINCTROW tblAufkopf.MahnungsDatum
    FROM tblAdressen INNER JOIN (tblAufkopf INNER JOIN tblMahntexte ON tblAufkopf.Mahnstufe = tblMahntexte.Zusatztext) ON tblAdressen.Adresse = tblAufkopf.Adresse
    WHERE (((tblAufkopf.MahnungsDatum)<=Date()-[TAGEzwischenMahnung]) AND ((tblAufkopf.Bearbeitungsindex)=4) AND ((tblAufkopf.RechnungsDatum) Is Not Null));

    NACHTRAG

    wenn ich die berechnung so mache geht es - jetzt bin ich ganz durcheinander

    SELECT DISTINCTROW [MahnungsDatum]+[TAGEzwischenMahnung] AS MahnungsDatumInclTage, tblAufkopf.MahnungsDatum
    FROM tblAdressen INNER JOIN (tblAufkopf INNER JOIN tblMahntexte ON tblAufkopf.Mahnstufe = tblMahntexte.Zusatztext) ON tblAdressen.Adresse = tblAufkopf.Adresse
    WHERE ((([MahnungsDatum]+[TAGEzwischenMahnung])<=Date()) AND ((tblAufkopf.Bearbeitungsindex)=4) AND ((tblAufkopf.RechnungsDatum) Is Not Null));


    • Bearbeitet MCDPone Mittwoch, 14. März 2012 09:07
    Mittwoch, 14. März 2012 08:58

Antworten

  • Hallo!

    Das letzte Beispiel funktioniert vermutlich, weil Access/Jet den Vergleich macht und diese Filterbedinung mit dem Datum nicht mehr an den Server weiterreicht, weil es ein Vergleich mit einem berechneten Wert ist (Tablescan und keine Index-Nutzung!).

    Problem bei deinem ersten Beispiel wird sein, dass du eine Zahl statt einem Datum erzeugst. Was genau passiert, sollte im Profiler zu erkennen sein. (Es kommt darauf an, welche Anweisungen von Jet an den Server weitergereicht werden.)

    Wenn du mit DateAdd rechnen würdest, wird es vermutlich funktionieren.

    WHERE tblAufkopf.MahnungsDatum <= DateAdd("d", -[TAGEzwischenMahnung], Date())

    Beim Filtern nach Datumswerten solltest du generell auf ein Datumsformat achten, da Jet und MSSQL unterschiedliche Startpunkte ihrer "Kalender" haben.

    MSSQL: select convert(datetime, 0, 112) => 1900-01-01

    Jet/VBA: format(cdate(0), "yyyy-mm-dd") => 1899-12-30

    Daher beim Filtern immer auf den Datumsdatentyp achten bzw. keine Zahlen sondern ein Datumsformat verwenden:

    WHERE tblAufkopf.MahnungsDatum <= 40994

    würde unterschiedliche Ergebnisse zw. Jet und MSSQL (wegen obig erwähnten Startpunkt) liefern.

    WHERE tblAufkopf.MahnungsDatum <= Date()

    sollte wieder passen.

    WHERE tblAufkopf.MahnungsDatum <= #2012-03-26#

    sollte auch richtig konvertiert werden.

    Du könntest die SQL-Anweisung auch im Server als gespeicherte Sicht unterbringen. Dann brauchst du nicht auf die passenden Konvertierung von Jet zum SQL-Server über ODBC achten.

    mfg
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch




    • Bearbeitet Josef Pötzl Montag, 26. März 2012 11:14
    • Als Antwort markiert MCDPone Dienstag, 27. März 2012 11:48
    Montag, 26. März 2012 10:13

Alle Antworten

  • Hallo!

    Das letzte Beispiel funktioniert vermutlich, weil Access/Jet den Vergleich macht und diese Filterbedinung mit dem Datum nicht mehr an den Server weiterreicht, weil es ein Vergleich mit einem berechneten Wert ist (Tablescan und keine Index-Nutzung!).

    Problem bei deinem ersten Beispiel wird sein, dass du eine Zahl statt einem Datum erzeugst. Was genau passiert, sollte im Profiler zu erkennen sein. (Es kommt darauf an, welche Anweisungen von Jet an den Server weitergereicht werden.)

    Wenn du mit DateAdd rechnen würdest, wird es vermutlich funktionieren.

    WHERE tblAufkopf.MahnungsDatum <= DateAdd("d", -[TAGEzwischenMahnung], Date())

    Beim Filtern nach Datumswerten solltest du generell auf ein Datumsformat achten, da Jet und MSSQL unterschiedliche Startpunkte ihrer "Kalender" haben.

    MSSQL: select convert(datetime, 0, 112) => 1900-01-01

    Jet/VBA: format(cdate(0), "yyyy-mm-dd") => 1899-12-30

    Daher beim Filtern immer auf den Datumsdatentyp achten bzw. keine Zahlen sondern ein Datumsformat verwenden:

    WHERE tblAufkopf.MahnungsDatum <= 40994

    würde unterschiedliche Ergebnisse zw. Jet und MSSQL (wegen obig erwähnten Startpunkt) liefern.

    WHERE tblAufkopf.MahnungsDatum <= Date()

    sollte wieder passen.

    WHERE tblAufkopf.MahnungsDatum <= #2012-03-26#

    sollte auch richtig konvertiert werden.

    Du könntest die SQL-Anweisung auch im Server als gespeicherte Sicht unterbringen. Dann brauchst du nicht auf die passenden Konvertierung von Jet zum SQL-Server über ODBC achten.

    mfg
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch




    • Bearbeitet Josef Pötzl Montag, 26. März 2012 11:14
    • Als Antwort markiert MCDPone Dienstag, 27. März 2012 11:48
    Montag, 26. März 2012 10:13
  • Hallo Josef

    danke für die ausführliche Antwort mit

    WHERE tblAufkopf.MahnungsDatum <= DateAdd("d", -[TAGEzwischenMahnung], Date())

    geht es - ich nutze zwar jetzt meine zweite variante aber es ist eben auch gut es zu verstehen wieso

    Als Sicht kann ICH es leider nicht speichern da die Anwendung sowohl auf mdb BE oder auf MSSQL BE zugreifen kann

    DANKE

    Michael

    Dienstag, 27. März 2012 11:51
  • Als Sicht kann ICH es leider nicht speichern da die Anwendung sowohl auf mdb BE oder auf MSSQL BE zugreifen kann

    Wie kannst du sie dann nicht als Sicht erstellen?

    Einmal verwendest du eine Access-Sicht/Abfrage und einmal verwendest du eine MSSQL-Sicht - je nachdem welches Backend verwendet wird.
    Wenn beide Sichten den gleichen Namen haben, bleibt die restliche Verwendung dieser Sicht/Abfrage unverändert.

    mfg
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch

    Dienstag, 27. März 2012 12:03
  • Ja schon nur verzichte ich
    lieber in Access auf eine Abfrage weil ich es der übersicht halber lieber in
    VBA als SQL String unterbringe - frag mich nicht wieso - hab ich mir so
    angewöhnt - klar kann ich jetzt erst nachschauen ob ich auf mssql oder mdb
    zugreife und den Code daraufhin anpassen.<o:p></o:p>

    Nur muss ich immer wenn
    ich im Code bin mir erst wieder die Sicht/Abfrage anschauen was ich dort genau
    Abfrage wenn ich das als SQL String im Code habe sehe ich das direkt.

    Ich denke mal ist auch
    eine reine Gewohnheitssache. <o:p></o:p>


    Dienstag, 27. März 2012 12:16
  • Hallo!

    Der Vorteil von Sichten ist für mich, dass ich bei Bedarf Server-seitig etwas ändern kann, ohne die Frontend-Anwendungen ändern zu müssen. Das ist sehr hilfreich, wenn man Änderungen im laufenden Betrieb (im aktiven DBMS) durchführen muss, da die User von so einer Änderung nichts merken - sie müssen nicht einmal das Frontend neu starten.

    Ich kaplse z. B. sehr gerne den Tabellenzugriff für ein Frontend über Sichten bzw. gespeicherte Prozeduren, damit ich bei Erweiterungen nicht den kompletten Frontend-Code durchsuchen und überarbeiten muss. Ich muss dann nur im Server die Sichten an die neue Struktur anpassen - und solange die Sicht nach außen gleich aussieht, ändert sich nichts für die Frontend-Anwendungen.

    Bezüglich "ich im Code bin mir erst wieder die Sicht/Abfrage anschauen was ich dort genau
    Abfrage wenn ich das als SQL String im Code habe sehe ich das direkt."

    Wie machst du das dann bei den Tabellen, die du für diese SQL-Anweisungen im VBA-Code verwendest? Kopierst du die auch als Text in das Modul? ... sonst musst du dort auch nachschauen - also im Prinzip kein Unterschied zur Sicht. ;-)

    [etwas OT]
    In der Access-CodeLib basteln wir gerade an einem SqlGenerator inkl. Converter für verschiedene DBMS. Vielleicht ist das für dich auch interessant. Damit kann man (wenn die Lib fertig ist) unabhängig vom DBMS/SQL-Dialekt eine SQL-Anweisung zusammensetzen und je nach Bedarf im gewünschten SQL-Dialekt verwenden. (Das ist zwar für DAO mit verknüpften Tabellen weniger wichtig, wird aber bei der Verwendung von ADODB mit OLEDB  und direkter Verbindung zum Server interessant.)

    Im Frontend kann dann das Erzeugen der SQL-Anweisungen unverändert bleiben. Man muss nur bei der Anwendungsinitialisierung die passenden Converter einstellen.

    ... für den Einsatz fehlt allerdings noch eine Kapselung für den Datenzugriff, damit man sich auch nicht mehr um das Erstellen der Recordsets usw. kümmern muss.

    mfg
    Josef


    Code-Bibliothek für Access-Entwickler
    AccUnit - Testen von Access-Anwendungen
    Virtueller Access-Stammtisch



    Dienstag, 27. März 2012 12:37