jankorte
Goto Top

Oracle DB - Select liefert Fehler aufgrund ungültigen Monats obwohl die betreffenden Zeilen ausgeschlossen sind

Ich habe einen Fehler in meinem Select, welcher mir ein ungültiges Datumsformat liefert. Durch diesen Fehler läuft der Select generell auf eine Exception hinaus.

Moin allerseits.

Vielleicht kann mir jemand mit einem Select weiterhelfen, der mich so langsam ratlos macht. Daher wollt ich mal gucken ob ihr da noch eine Lösung wisst.

SELECT SUM(ZZLIEFG - ZZRUECKG) 
FROM ZSD_PALETTEN_VIEW 
WHERE wadat_ist != 00000000 
and ZZPAL_ART = to_number('" & Hauptfenster.ComboBox_StatBestPalchooser.SelectedValue & "')    
and to_date(WADAT_IST, 'YYYYMMDD') <= to_date('" & datumlast & "', 'DD.MM.YYYY HH24:MI:SS')  


nicht wundern, da sind teile von VisualBasic.Net drin. Der select wird von einem Programm ausgeführt welches den Bestand von Paletten zu einem bestimmten Zeitpunkt ausgibt.
Das betreffende Datumsfeld hat die bezeichnung "wadat_ist"

Die falschen Werte im Feld "wadat_ist" die NICHT verändert werden dürfen haben den Wert "00000000"


Problem ist:
- es gibt falsche Datumseinträge in der Tabelle, die ich aufgrund angeschlossener SAP Systeme nicht ändern kann
- das Feld wo das datum enthalten ist ist vom Typ VARCHAR2(8), was natürlich unpraktisch ist aber nicht verändert werden darf (ebenso wegen SAP)

Any Ideas?

Gruß,
Jan

Content-ID: 131698

Url: https://administrator.de/forum/oracle-db-select-liefert-fehler-aufgrund-ungueltigen-monats-obwohl-die-betreffenden-zeilen-ausgeschlossen-131698.html

Ausgedruckt am: 23.12.2024 um 16:12 Uhr

Biber
Biber 15.12.2009 um 11:27:11 Uhr
Goto Top
Moin Jan Korte,

... WHERE wadat_ist != 00000000
Erwähntest du nicht, dass wadat_ist eigentlich ein VARCHAR2(8)-Feld ist?
Wäre dann nicht
...WHERE wadat_ist != '00000000'
...ein besserer Einstieg?

Zusatzfragen:
  • Wie gehst du denn inhaltlich mit den "ungültigen" Datumswerten um? Fallen die vollkommen unter den Tisch?
  • wenn ja - wieso filterst du die nicht komplett raus schon im ZSD_PALETTEN_VIEW?
  • wenn nein - warum setzt du die nicht schon im eben genannten View auf einen "erkennbaren" Wert von z.B. '31.12.9999' oder ähnlich, damit sie logisch richtig verarbeitbar sind?

Grüße
Biber
JanKorte
JanKorte 15.12.2009 um 14:12:57 Uhr
Goto Top
klar,... die Anführungszeichen. Die hatte ich jetzt beim Übertragen vergessen, sind aber vorhanden. Da ich nicht persönlich für den View verantwortlich bin habe ich die Anpassung mal grad weitergegeben.

Wenns was neues gibt meld ich mich nochmal, ansonsten vielen Dank für den Hinweis auf die Banalität die ich übersehen hab ^^.

Gruß, Jan
JanKorte
JanKorte 15.12.2009 um 15:11:12 Uhr
Goto Top
Also,.. der Fehler besteht weiterhin.

Es muss in der Tabelle wohl mehrere Einträge geben, die kein Datumsformat besitzen. Da hilft es mir auch nicht die Einträge mit dem Wert '00000000' auszufiltern, weil es noch hunderte andere gibt, die ein falsches Format besitzen.

Dumm gelaufen.

Gibt es nicht irgendeine Abfrage, die ungültige Datumsfelder findet und anzeigt? Bzw. eine Selectanweisung mit der man die ausfiltern kann ohne jeden einzelnen Eintrag zu durchsuchen?

Hoffnungslose Sache im Moment. Ich hoffe Ihr wisst Rat .


Gruß, Jan
Biber
Biber 15.12.2009 um 15:35:09 Uhr
Goto Top
Moin Jan Korte,

Hoffnungslose Sache im Moment
Na ja, wenn du meine Ex-Schwiegermutti kennengelernt hättest, dann würdest du nicht so leichtfertig mit dem Begriff "hoffnungslos" umgehen.

Also, richtig ist: Oracle kennt von Haus aus keine vorgefertigte IsDate()-Funktion, die du ja eigentlich brauchst.

Aber: Ja hey! Dann braten wir halt eine zusammen. Denn ein Oracle-Server ist ja offensichtlich im Hintergrund, und der hat immer Spaß an so was.

Eine einfache (aber ausreichende) Implemetierungsskizze findest du z.B bei AskTom,
eine etwas aufwändigere (aber brauchbarere) hier.

Irgendwo zwischen diesen beiden Extremen solltest du deine passende Lösung zusammenschroten.

Grüße
Biber
JanKorte
JanKorte 15.12.2009 um 16:27:01 Uhr
Goto Top
So,

ich habe dann mal ne Funktion eingebaut und hab die daten mit folgender Funktion getestet:

create or replace
function IsDate (str varchar2) return varchar2 is
inDate varchar2(40);

FUNCTION dateCheck (inputDate varchar2, inputMask varchar2)
RETURN varchar2
IS
dateVar date;

BEGIN
dateVar:= to_date(inputDate,inputMask);
return 'true';  
exception
when others then
return 'false';  
END;

BEGIN
inDate:= trim(str);
if dateCheck(inDate, 'yyyymmdd') = 'false'  
then
return 'false';  
else
return 'true';  
end if;
END;

Soweit so gut.

Der Testquery lautete folgendermaßen:

Select wadat_ist, isdate(wadat_ist) from zsd_paletten_view;

Hier wurde kein Fehler in der Datenbanktabelle gefunden bis auf die mit '00000000' was mit ja generell zeigt das ISDATE() funktioniert.

Habe ich aber nun den Select erweitert und:

Select to_date('wadat_ist', 'YYYYMMDD'), isdate(wadat_ist) from zsd_paletten_view where isdate(wadat_ist) = 'true';  


angegeben, haut der mir wieder einen Fehler raus:
Error report:
SQL Error: ORA-01841: (Volles) Jahr muss zwischen -4713 und +9999 liegen und darf nicht 0 sein
01841. 00000 -  "(full) year must be between -4713 and +9999, and not be 0"  
*Cause:    Illegal year entered
*Action:   Input year in the specified range

Irgendwie hab ich das Gefühl das mich da wer nicht mag ^^
Biber
Biber 15.12.2009 um 16:40:09 Uhr
Goto Top
Moin Jan Korte,

Zitat von @JanKorte:

Irgendwie hab ich das Gefühl das mich da wer nicht mag ^^
Na ja, wenn du meine Ex-Schwiegermutti kennengelernt hättest, dann würdest du nicht so leichtfertig mit dem Begriff .....

Könnte es daran liegen, dass das Funktionsargument von to_date() ein konstanter String ist?
Select to_date('wadat_ist', 'YYYYMMDD')

Grüße
Biber
JanKorte
JanKorte 15.12.2009 um 19:04:03 Uhr
Goto Top
jau,.. zumindestens das war ein Flüchtigkeitsfehler.

haben den View jetzt angepasst und ihm in seinen eingenen select folgendes gegeben;

CREATE OR REPLACE FORCE VIEW "PALETTEN"."ZSD_PALETTEN_VIEW" ("MANDT", "KUNAG", "KUNNR", "ZZPAL_ART", "WADAT_IST", "VBELN", "VTEXT", "ZZLIEFG", "ZZRUECKG", "NAME1", "NAME2") AS   
  SELECT "MANDT",  
          "KUNAG",  
          "KUNNR",  
          "ZZPAL_ART",  
        "WADAT_IST",  
          "VBELN",  
          "VTEXT",  
          "ZZLIEFG",  
          "ZZRUECKG",  
          "NAME1",  
          "NAME2"  
     FROM zsd_paletten@sap_prod
     WHERE isdate(wadat_ist) = 'true';  

die Zeile
WHERE isdate(wadat_ist) = 'true';  

sollte jetzt jeglichen Müll aus dem View filtern, was aber bei meiner Abfrage via Programm nicht so scheint.

Es wird immernoch der Fehler "Not a valid Month" angezeigt. So langsam hab ich Oracle gefressen. Wenn doch laut ISDATE() kein falscher Monat mehr im View vorhanden sein KANN, dann sollte die vor einigen Beiträgen erwähnte SQL Abfrage doch funktionieren?!

So langsam scheine ich deine Ex-Schwiegermutti zu kennen. *gg*

Gruß, Jan

PS: Gut,... Oracle kann nix dafür das da so besch.... Daten in den Tabellen stehen, aber es könnte mir wenigstens ein kleines bischen helfen die wieder loszuwerden.
Biber
Biber 15.12.2009 um 19:35:19 Uhr
Goto Top
Moin Jan Korte,

kein Oracle dieser Welt kann so widerborstig sein wie meine Ex-Schwiegermutti... das knacken wir *gg

Dennoch - ich sehe auch (noch) nicht den logischen Trugschluss in "unserer" Vorgehensweise...
Die IsDate()-Funktion habe ich auch testweise bei mir (Oracle 10/11) installiert und okay, die works as designed.
Gut, ist ein bisschen albern mit den String-Rückgaben 'true' und 'false'.. das hätte ich evtl. ein bisschen anders gelöst.
Außerdem - was nicht mit deiner Fehlermeldung korrespondiert - sowohl "gültige" Datumsangaben aus dem Jahr 0 wie auch negative Jahreszahlen liefern mit der IsDate()-Funktion ein 'false'. hab ich jetzt nicht wirklich verstanden, aber hilft ja auch jetzt nicht weiter.

Also, dann wäre doch der nächste Schritt zur Lokalisierung der Sollbruchstelle, alle Sätze rauszupfriemeln, die laut Isdate(wadat_ist) 'true' zurückliefern, bei denen aber der Monat (Pos 5/6 des Varchar-Strings) nicht zwischen 1 und 12 liegt..

SELECT * from PALETTEN.ZSD_PALETTEN_VIEW
Where isdate(wadat_ist) = 'true'  
And ( Substr(wadat_ist, 5, 2) < '01'  or Substr( wadat_ist, 5, 2) >'12' )  
oder so ähnlich

Grüße
Biber
JanKorte
JanKorte 15.12.2009 um 21:07:33 Uhr
Goto Top
Moin Biber,

das alles klingt sehr sinnvoll, ist es sicherlich auch. Bin allerdings nicht mehr in der Firma und werde deswegen morgen weitergucken. Hab für heute erstmal die Schnauze voll.
Ich danke dir aber schonmal für die geleistete Hilfe und wünsche dir einen erholsamen Abend.

Bis Morgen mit Response zu der Select Erweiterung

Gruß, Jan
JanKorte
JanKorte 08.05.2010 um 17:44:46 Uhr
Goto Top
Update zum Abschluss: Die Funktion IsDate hat funktioniert. Mein Programm läuft jetzt einwandfrei.

Vielen Dank Biber!!
Biber
Biber 10.05.2010 um 07:30:08 Uhr
Goto Top
Moin Jan Korte,

danke für die Rückmeldung und Gratulation zur erfolgreichen Lösung.

Interessehalber: war denn noch eine Änderung/Verfeinerung der IsDate()-Funktion nötig?

Grüße
Biber
JanKorte
JanKorte 13.05.2010 um 17:22:47 Uhr
Goto Top
Moinsen,

die IsDate()-Funktion hat so gereicht wie angegeben. Ich habe nur hier und da in der Abfrage noch ein paar Sachen ausgeschlossen, welche allerdings nichts mit dem Datum zu tun hatten.

Vielen Dank für deine Hilfe. Ich revanchier mich gern mal sobald ich die Chance dazu bekomme ^^

Gruß, Jan