Announcement

Collapse
No announcement yet.

Datumsproblem bei SQL Abfrage

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Datumsproblem bei SQL Abfrage

    Hallo Zusammen

    Ich habe ein problem mit einer SQL Abfrage auf eine Oracle 11 DB. In dem Script wird mit dem Datum noch eine Berechnung durchgeführt. Führe ich das Script im Tool "TOAD FOR ORACLE" aus, erhalte ich den gewünschten Wert. Führe ich das Script jedoch via SSIS oder SQL Developer aus so wird das Datum falsch berechnet. Wie kann es sein, dass ein Script, dass auf den selbe DB greift unterschiedliche Werte liefert?

    Gruss

  • #2
    Spendiere eine hier von

    http://de.wikipedia.org/wiki/Glaskug...Okkultismus%29

    oder es könnte sinnvoll sein, den Code zu zeigen
    Christian

    Comment


    • #3
      Also das ist ein Auszug des Codes, der nur teilweise funktioniert:

      when (substr(to_date(sysdate,'dd.mm.yyyy'),-4) - substr(to_date(c.B003_PRIVATGEBURTSTAG,'dd.mm.yyyy '),-4)) between 28 and 32 then

      Wenn ich das to_date durch das to_char ersetzte, dann funktioniert es auf allen System. Trotzdem ging ich immer davon aus, dass das Tool das Script nur absetzt und der Oracle Server es umsetzt und das entsprechende Ergebnis zurück liefert.

      Comment


      • #4
        Das Teil enthält einige Logikfehlern. Wenn ich das recht verstehe, möchtest Du alle Sätze finden, die sich zwischen 28 und 32 Tage von c.B003_PRIVATGEBURTSTAG unterscheiden?
        Code:
        where sysdate-c.B003_PRIVATGEBURTSTAG between 28 and 32
        Fertig. Im anderen SQL werden Datumsfelder nochmal in Datumsfelder umgewandelt (wieso) und dann impliziet in Strings konvertiert, wobei die Ländereinstellungen des Clientprogramms hier ins Spiel kommen. Diese ist ggf. bei Toad und SQLDeveloper unterschiedlich, womit dein substr andere Werte liefert. to_char ist genau dafür da und deshalb käuft es auf allen Systemen.

        Dim
        Zitat Tom Kyte:
        I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

        Comment


        • #5
          Also eigentlich wollte ich nur das Alter ermitteln Deshalb rechne ich das Jahr vom Systemdatum minus das Jahr vom Geburtsdatum

          Comment


          • #6
            Originally posted by sqldev View Post
            Also eigentlich wollte ich nur das Alter ermitteln Deshalb rechne ich das Jahr vom Systemdatum minus das Jahr vom Geburtsdatum
            Dann nimm doch einfach dieses hier:

            [HIGHLIGHT=sql]
            EXTRACT(YEAR FROM (SYSDATE - c.B003_PRIVATGEBURTSTAG) YEAR TO MONTH )
            [/HIGHLIGHT]

            Gruss

            Comment


            • #7
              Vielen Dank für die Hilfe!

              @Wernfired Das Problem ist, dass auf diese Weise das Jahr exakt nach dem Geburtsdatum berechnet wird. Beispiel: Geburtsdatum: 19.11.1983 Systemdatum: 26.10.2012 = 28. Wenn ich nur mit den Jahren rechne gibt es 29. Für meine Zweck muss es leider auf Grund des Jahres ermittelt werden also 29 wäre richtig. Ich hoffe man versteht was ich meine

              Comment


              • #8
                Du meinst sowas:
                Code:
                to_number(to_char(sysdate,'yyyy')) - to_number(to_char(c.B003_PRIVATGEBURTSTAG,'yyyy'))
                Dim
                Zitat Tom Kyte:
                I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

                Comment


                • #9
                  Interessant wie viele Leute immer wieder versuchen ein Datum hin und her in eine Zahl oder Text umzuwandeln, nur um damit zu rechnen.

                  Dabei ist doch eigentlich alles vorhanden:
                  [HIGHLIGHT=sql]
                  EXTRACT(YEAR FROM (TRUNC(SYSDATE, 'YYYY') - TRUNC(c.B003_PRIVATGEBURTSTAG, 'YYYY') ) YEAR TO MONTH )
                  [/HIGHLIGHT]

                  Gruss

                  Comment


                  • #10
                    Hallo,
                    das von Wernfried scheint mir auch nicht DAtumsgenau zu sein.
                    [HIGHLIGHT=sql]
                    with data as (
                    select TO_DATE('29.10.1989') DATUM, 'meier' name from DUAL union all
                    select TO_DATE('30.10.1989') DATUM, 'müller' name from DUAL)
                    select FLOOR (MONTHS_BETWEEN (sysdate, DATUM) / 12), name from data;

                    [/HIGHLIGHT]

                    Gruß

                    Martin

                    Comment


                    • #11
                      Auch wenn es schon funktionierende Lösungen gibt und der TE wahrscheinlich nie wieder hier rein schaut, wollte ich noch einen Hinweis loswerden, weil es hier beispielhaft schlecht gemacht ist, irgendwie im Thread untergegangen ist und eine ständige Fehlerquelle darstellt.

                      Originally posted by sqldev View Post
                      when (substr(to_date(sysdate,'dd.mm.yyyy'),-4) - substr(to_date(c.B003_PRIVATGEBURTSTAG,'dd.mm.yyyy '),-4)) between 28 and 32 then
                      to_Date(sys_Date,..) und vermutlich auch das folgende to_date(c.B003.. ist absoluter Müll. (@TE: bitte nicht persönlich nehmen. )
                      Eine to_date Konvertierung, die als Input ein Wert vom Typ Datum erhält funktioniert nur zufällig, wenn alle Parameter "stimmen". Es muss bei diesem Aufruf implizit zwischen Datum und Text konvertiert werden. Das substr drumrum macht das gleiche in umgekehrter Form. Substr erwartet einen Text als Parameter, bekommt aber ein Datum. Auch hier muss wieder "automatisch" konvertiert werden.
                      Alle diese Konvertierungen erfolgen auf Basis der NLS Settings des "Systems". Das System besteht aus der DB, dem DB Client, den Ländereinstellungen des OS und dem laufenden Programm, das diese Einstellungen je nach dem nochmals ändert.
                      Dann wird zuletzt das substr Ergebnis (ein Text) noch mit einem anderen Substr Ergebnis verrechnet. Das geschieht natürlich auf Basis von Zahlen. Wieder eine implizite Konvertierung. Nicht weiter dramatisch, sofern alle vorigen impliziten Konvertierungen zufällig auf Punkt und Komma gepasst haben und der Ergebnis-Text nun auch wirklich keine Zeichen enthält, die eine Zahlkonvertierung verhindern.

                      Als Ausdruck einmal umgesetzt:
                      ..substr(to_date(sysdate,'dd.mm.yyyy'),-4) - xy ..
                      wird intern ungefähr zu folgendem Ausdruck evaluiert:
                      .. to_number(substr(to_char(to_date(to_char(sysdate,'default fmt date mask'),'dd.mm.yyyy'), 'default fmt date mask'), -4)) - xy ..
                      Ich habe die original Ausdrücke fett gemacht, der Rest wird vom System ergänzt und mit default parametern belegt.

                      Auch wenn es bequem ist, implizite Konvertierung zu nutzen, gerade bei Datumsrechnerei ist eher gefährlich, weil das Ergebnis von den Ländereinstellungen des Systems abhängt.
                      Gruß, defo

                      Comment

                      Working...
                      X