[meta]Interbase IB Firebird FB Stored Procedure Proc SP UDF Length [/meta]
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).
Zuerst wird eine (bekannte) Hilfsfunktion benötigt:
FILLCHAR
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| 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
alanti.net/firebird/marathon/ ) oder QuickDesk als Frontend bemüht werden.
Dann kommt die eigentliche Funktion zum Tragen:
GETLENGHT
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| CREATE PROCEDURE GETLENGTH ( 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.
Um diese Funktion direkt in der Datenbank benutzen zu können kann man zum Beispiel wie folgt vorgehen:
TEST_GETLENGTH
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| CREATE PROCEDURE TEST_GETLENGTH AS DECLARE VARIABLE L INTEGER; DECLARE VARIABLE S VARCHAR(255); DECLARE VARIABLE Meldung VARCHAR(255); BEGIN L = 0; MELDUNG = ''; S = '12345678901234567890'; EXECUTE PROCEDURE GETLENGTH ( :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
/* und so weiter ... */
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ß beim "Eskiuellen",
Loïs Bégué
Moderiert von Udontknow: Meta-Tags hinzugefügt, Prozedurnamen korrigiert.