Es gibt natürlich verschiedene Ansätze. Nicht zuletzt bieten UDFs
(User Defined Function) entsprechendes.
Kommen UDFs nicht in Frage (z.B. in einem Novell-Netzwerk) und sollte
die Client-Anwendung nicht bemüht werden (um den "Traffic" nicht zu
erhöhen), dann muß die Berechnung in der Datenbank selbst stattfinden
(Fat Server Prinzip).
1) Zuerst wird eine (bekannte) Hilfsfunktion benötigt: FILLCHAR
---------------------------------------------------------------
CREATE PROCEDURE FILLCHAR (
AFILLCHAR CHAR (1),
ARESULTLEN INTEGER)
RETURNS (
ARESULTSTRING VARCHAR (255))
AS
DECLARE VARIABLE ACOUNTER INTEGER;
BEGIN
ARESULTSTRING = ' ';
ACOUNTER = 0;
While ( :ACOUNTER < :aResultLen ) Do
Begin
ARESULTSTRING = :ARESULTSTRING || :aFillChar;
ACOUNTER = :ACOUNTER + 1;
END
SUSPEND;
END
Anmerkung:
Das "Suspend" dürfte überflüssig sein.
Allerdings läßt sich dann die Funktion nicht "debuggen", wenn z.B.
Marathon (siehe http://alanti.net/firebird/marathon/ ) oder QuickDesk
als Frontend bemüht werden.
(throw the suspend away, if you don't need to debug)
2) Dann kommt die eigentliche Funktion zum Tragen: GETLENGHT
------------------------------------------------------------
CREATE PROCEDURE GETLENGHT (
INPUTSTRING VARCHAR (255))
RETURNS (
THELENGTH INTEGER)
AS
DECLARE VARIABLE LCOUNTER INTEGER;
DECLARE VARIABLE DUMMYSTRING VARCHAR(255);
DECLARE VARIABLE TEMPSTRING VARCHAR(255);
DECLARE VARIABLE C CHAR(1);
BEGIN
THELENGTH = 0;
DUMMYSTRING = '';
C = '0';
LCOUNTER = 0;
TEMPSTRING = '';
if (:INPUTSTRING IS NULL) then
BEGIN
EXIT;
END
WHILE (LCOUNTER < 255) DO
BEGIN
TheLength = :LCOUNTER;
EXECUTE PROCEDURE FILLCHAR ( :C, :LCOUNTER ) RETURNING_VALUES :DUMMYSTRING;
TEMPSTRING = Cast ( :INPUTSTRING || :DUMMYSTRING as CHAR(255));
LCOUNTER = LCOUNTER + 1;
WHEN ANY DO
BEGIN
TheLength = 255 - :LCOUNTER;
SUSPEND;
EXIT;
END
END
SUSPEND;
END
Anmerkungen:
Auch hier dürfte man sich die "SUSPEND" im Normalbetrieb ersparren
können...
Die maximale Länge des zu prüfenden String wurde willkürlich auf
255 Zeichen gesetzt. Bei Bedarf kann man diesen Wert "vorsichtig"
anpassen: Wird dieser Wert zu groß gewählt und werden kleine
Zeichenketten mit dieser Funktion bearbeitet, dann erhöht sich
natürlich die Dauer der Verarbeitung entsprechend.
3) Usage:
---------
CREATE PROCEDURE TEST_GETLENGHT
AS
DECLARE VARIABLE L INTEGER;
DECLARE VARIABLE S VARCHAR(255);
DECLARE VARIABLE Meldung VARCHAR(255);
BEGIN
L = 0;
MELDUNG = '';
S = '12345678901234567890';
EXECUTE PROCEDURE GETLENGHT ( :S ) RETURNING_VALUES :L;
/* ab hier steht in "L" die Länge des Strings "S" */
IF (L<21) THEN
BEGIN
MELDUNG = 'Noch ' || CAST( ( 20 - :L ) as VARCHAR(3)) || ' Zeichen übrig...';
END
ELSE
BEGIN
MELDUNG = 'Stringlänge = ' || CAST( :L as VARCHAR(3)) || ' => String zu lang! (maximal 20 Zeichen)';
END
/* ... */
SUSPEND;
END
Bemerkungen:
Es lassen sich viele andere String-Funktionen mittels Stored
Procedures nachbilden.
Allerdings ist eine Datenbank bzw. einen Datenbank-Server nicht
besonders dafür ausgelegt... Zumindest nicht, wenn rechenintensive
Aufgabe anfallen.
Andererseits kann die Anwendung solchen "Tricks" die Menge der
zwischen Client und Server übertragenen Daten erheblich reduziert
werden: gewisse Prüfungen können dann VOR der Datenübertragung
stattfinden.
Viel Spaß
|