In FireBird 2.0
- und auch nur hier -
ist es möglich, dass UDFs auch <null> zurückliefern
anstelle von “0" bzw. “leerem String”. Z.B. liefert folgender SQL
SELECT F_LEFT(NULL, 5) FROM RDB$DATABASE
bisher einen “leeren String" zurück, was aber eigentlich falsch ist.
Richtig wäre hier <null>.
Um nun aber das bisherige Verhalten - wenn gewünscht - beizubehalten
und ALTERNATIV dazu ein “richtiges” Verhalten zu ermöglichen wurde
in
FireBird 2.0 die Möglichkeit geschaffen, durch die Deklaration der
UDF
das gewünschte Verhalten festzulegen.
Deklariere ich - für unser Beispiel
DECLARE EXTERNAL FUNCTION F_LEFT
CSTRING(254),
INTEGER
RETURNS CSTRING(254) FREE_IT
ENTRY_POINT 'left' MODULE_NAME
'FreeAdhocUDF'
ist das Verhalten wie gewohn: ein <null>-Input erzeugt
einen “leeren” String
Deklariere ich aber
DECLARE EXTERNAL FUNCTION F_LEFT
CSTRING(254) NULL,
INTEGER NULL
RETURNS CSTRING(254) FREE_IT
ENTRY_POINT 'left' MODULE_NAME
'FreeAdhocUDF'
liefert ein <null>-Input auch ein <null>
zurück.
Siehe dazu auch die Release-Notes zu FireBird 2.0
Wir haben alle
UDFs mit einem oder
mehreren Input-Parametern für diese Möglichkeit angepaßt.
Generell gilt, dass alle
Funktionen das Gleiche zurückliefern wie früher.
Erst wenn man sie anders deklariert oder einen anderen Etrypoint
benutzt verändern sie ihr Verhalten so, dass sie auch
<null>
zurückliefern können.
Generell gilt, dass wenn mindestens
einer der Input-Parameter
<null> ist, ist der Output auch <null>.
Wo darüber hinaus noch andere Konstellationen <null>
zurückliefern bzw. es Varianten gibt, die auch <null>
zurückliefern können, ist dies in der Übersicht mit einem *
gekennzeichnet und bei den Funktionen vermerkt.
Um nun in bestehenden
Datenbanken dieses Verhalten zu ändern, muß man
die bestehen UDFs entfernen und mit der neuen Deklaration neu
anlegen -
was häufig nicht geht, denn die UDFs lassen sich wg.
Abhängigkeiten nicht entfernen - gibt es die Möglichkeit per UPDATE
auf
die RDB$FUNCTION_ARGUMENTS System-Tabelle dies zu ändern.
Dazu muß der Wert der Spalte RDB$MECHANISM auf 5 gesetzt werden, und
zwar für die Parameter, die die Funktionalität NULL erhalten sollen,
hier PARAMETER 1 und PARAMETER 2. Der UPDATE sähe dann für unser
Beispiel so aus:
UPDATE RDB$FUNCTION_ARGUMENTS
SET RDB$MECHANISM = 5
WHERE RDB$FUNCTION_NAME = 'left'
AND RDB$ARGUMENT_POSITION IN (1, 2);
Bei vielen Funktionen ergab sich außerdem die Notwendigkeit, den
Aufruf
- und damit die Deklarationen - grundlegend
zu ändern.
Aus einem "RETURN INTEGER BY VALUE" muß z.B. ein "RETURN INTEGER
FREE_IT" werden - auch wenn man die <null>Rückgabe nicht
benutzen
möchte. Um sie benutzen zu können mußten wir die Funktion derart
ändern, daß eine ältere Deklaration mit "BY VALUE" nun eben nicht
mehr
funktioniert.
Am einfachsten ist auch hier: alte UDFs löschen und mit neuem Script
neu anlegen.
|