Ich habe Probleme mit einer Mammut-Legacy-PL/SQL-Prozedur, die die folgenden Logik:Kann dbms_utility.get_time Rollover?
l_elapsed := dbms_utility.get_time - l_timestamp;
wo l_elapsed
und l_timestamp
vom Typ sind PLS_INTEGER
und l_timestamp
hält das Ergebnis eines vorherigen Aufruf get_time
Diese Linie begann plötzlich während eines Batch-Lauf mit einem ORA-01426: numeric overflow
Fehler. Die Dokumentation auf get_time
ist ein bisschen vage, möglicherweise absichtlich so, aber es ist schlägt vor, dass der Rückgabewert keine absolute Bedeutung hat und so ziemlich jeder numerische Wert sein kann. So war ich verdächtig zu sehen, dass es einer PLS_INTEGER
zugewiesen wird, die nur 32-Bit-Ganzzahlen unterstützen kann. Das Interweb ist jedoch voll mit Beispielen von Leuten, die genau so etwas tun.
The Smoking Gun gefunden wird, wenn I get_time
manuell aufrufen, wird ein Wert von -214.512.572 zurückkehrt, die verdächtig nahe der min-Wert eines 32-Bit-Ganzzahl mit Vorzeichen ist. Ich frage mich, ob während der Zeit zwischen dem ersten Aufruf an get_time
und dem nächsten, interne Oracle-Zähler von seinem maximalen Wert und seinem minimalen Wert gerollt ist, was zu einem Überlauf führt, wenn versucht wird, einen von dem anderen zu subtrahieren.
Ist das eine wahrscheinliche Erklärung? Wenn ja, ist das ein inhärenter Fehler in der get_time
-Funktion? Ich könnte nur abwarten und sehen, ob die Charge heute Nacht noch einmal fehlschlägt, aber ich bin daran interessiert, eine Erklärung für dieses Verhalten vorher zu bekommen.
Agh, was für eine grässliche Sauerei. Danke für die Klarstellung. Ich werde jetzt sicher in dem Wissen ruhen, dass ich warten kann, bis der DBA aus den Ferien zurückkehrt, und ihm das höllische Ding aufdrängen. – skaffman