Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Firebird Procedure liefert null (https://www.delphipraxis.net/192588-firebird-procedure-liefert-null.html)

MichaelT 4. Mai 2017 11:27

AW: Firebird Procedure liefert null
 
Das ist einzige Platz in dem ein potentiell nicht initialisierter Wert zugewiesen wird.

IF (LE_EK <= 0 ) THEN
LE_EK = ART_EKNETTO;

Wäre LE_EK = NULL bspw. dann gilt die Bedingung nicht.

Soviel verbleibt nicht, als dass eine NULL zurückkäme.

Auf Businessebene ist der Satz nicht 'gültig' oder 'leer'. Testdatensätze, Fehlersätze oder wie auch immer. Zumal die ohne DATUMs Einschränkung offensichtlich zurückkommen und/oder insbesondere dann...

Auf ART_EKNETTO wird vermutlich einfach nicht hingeschreiben zuvor. NULL wird zugewiesen und das Logging liefert keine Ergebnis. So in etwas stelle ich mir das vor, rein auf Verdacht.

Zum Log
VALUE || NULL -> NULL



Code:
SET TERM ^ ;
CREATE PROCEDURE P_GETLAGERWERT (
    DATUM Date )
RETURNS (
    LGWERT Numeric(12,2) )
AS
DECLARE ARTNR VARCHAR(50);
DECLARE BEREINH NUMERIC (10,3);
DECLARE LGNR INTEGER;
DECLARE LE_EK NUMERIC (12,4);
DECLARE ART_EKNETTO NUMERIC (12,4);
DECLARE BESTAND NUMERIC (11,3);
DECLARE BER_BESTAND NUMERIC (11,3);
DECLARE BEST_OHNE_RECHNUNG NUMERIC (11,3);
DECLARE ART_WERT NUMERIC (12,3);
BEGIN
  LGWERT = 0;
 
   
    ARTNR = NULL;
    LGNR = NULL;
    BEREINH = NULL;
    ART_EKNETTO = 0;
     -- BESTAND = (SELECT BESTAND from P_GETBEST_ATDATE(:ArtNr, :LGNR, '*', '*', :DATUM));
      BESTAND = NULL;
      BEST_OHNE_RECHNUNG = NULL;
      IF ( BESTAND is NULL ) THEN
        BESTAND = 0;
       
      IF (BEST_OHNE_RECHNUNG IS NULL) THEN
          BEST_OHNE_RECHNUNG = 0;
      LE_EK = 0;
      IF (LE_EK <= 0 ) THEN
        LE_EK = ART_EKNETTO;
       
      IF ((BEREINH IS NULL) OR (BEREINH = 0)) THEN
        BEREINH = 1;
   
      IF (BESTAND IS NULL) THEN
        BESTAND=0;
   
      BER_BESTAND = BESTAND - BEST_OHNE_RECHNUNG;
      IF ( BER_BESTAND < 0 ) THEN
        BER_BESTAND = 0;
         
      ART_WERT = ( BER_BESTAND * LE_EK / BEREINH);
       
      LGWERT = LGWERT + ART_WERT;
      /* Protokoll */
   
 SUSPEND;
END^
SET TERM ; ^
GRANT EXECUTE
 ON PROCEDURE P_GETLAGERWERT TO SYSDBA;
Zitat:

Zitat von hoika (Beitrag 1370084)
Hallo,
Leerzeile?

aber mal weiter

Zitat:

Die Procedure läuft intern absolut korrekt ab. Das habe ich aus der Procedure heraus protokolliert. Die Rückgabe-Variable ist bis zum Schluss absolut korrekt berechnet! Da fallen joins's oder Nullwerte wohl aus.
Mach mal vorm Suspend ein LGWERT=21.0;
Und dahinter noch einen Protokolleintrag.

Kommt jetzt immer noch NULL raus als Ergebnis und steht die 21.0 im Log?


Jasocul 4. Mai 2017 12:40

AW: Firebird Procedure liefert null
 
Ich bin sicher nicht der Firebird-Spezi, aber was passiert eigentlich hier
Code:
(cast( al.LgNr as Integer) >0 )
wenn LgNr nicht als Integer ge-castet werden kann?

Kann es sein, dass dann für alle funktionierenden Datensätze ein Protokoll geschrieben wird, aber im Fehlerfall die SP im ungültigen Zustand abbricht und dann einen Null-Wert liefert?
Das Protokoll hätte dann zwar Daten, aber ob die vollständig sind, ist nicht geklärt, oder?


Folgendes ist mir auch noch aufgefallen:
SQL-Code:
INTO :ARTNR, :LGNR, BEREINH, ART_EKNETTO
Dort fehlen Doppelpunkte. Wurde zwar irgendwo schon geschrieben, aber ich habe keine Antwort darauf gesehen.

Die Folge könnte sein, das ART_EKNETTO Null ist.
In dem Fall wäre hierdurch
SQL-Code:
LE_EK = (SELECT LE_EK FROM P_GET_LEEK_STICHTAG(:ARTNR, :LGNR, :DATUM));
       IF (LE_EK <= 0 ) THEN
         LE_EK = ART_EKNETTO;
LE_EK auch Null, sobald LE_EK <= 0 ist.
Das muss aber wohl jemand mit genaueren Firebird-Kenntnissen klären.

MichaelT 4. Mai 2017 14:05

AW: Firebird Procedure liefert null
 
SQL-Code:
  IF (LE_EK <= 0 ) THEN
Wen LE_EK IS NULL, dann wird der Ausdruck false. Der ART_EKNETTO wird hernach nirgends mehr verwendet und auch nicht protokolliert. Ohne : gibt es keine Binding der Variable.

Selbst wenn liefert die Protokollzeile NULL durch '||'. (SQL)

Ich arbeite deswegen lieber mit Records und die innere Logik in eine eigene Funktion gepackt. Damit kann man einen Art Unittest machen.


Zitat:

Zitat von Jasocul (Beitrag 1370173)
Folgendes ist mir auch noch aufgefallen:
SQL-Code:
INTO :ARTNR, :LGNR, BEREINH, ART_EKNETTO
Dort fehlen Doppelpunkte. Wurde zwar irgendwo schon geschrieben, aber ich habe keine Antwort darauf gesehen.

Die Folge könnte sein, das ART_EKNETTO Null ist.
In dem Fall wäre hierdurch
SQL-Code:
LE_EK = (SELECT LE_EK FROM P_GET_LEEK_STICHTAG(:ARTNR, :LGNR, :DATUM));
       IF (LE_EK <= 0 ) THEN
         LE_EK = ART_EKNETTO;
LE_EK auch Null, sobald LE_EK <= 0 ist.
Das muss aber wohl jemand mit genaueren Firebird-Kenntnissen klären.



Alle Zeitangaben in WEZ +1. Es ist jetzt 11:01 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz