Autor Beitrag
Loïs Bégué
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Di 22.06.04 14:08 
[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
ausblenden 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
ausblenden volle Höhe 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:
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
ausblenden 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


:idea: 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", :D

Loïs Bégué

Moderiert von user profile iconUdontknow: Meta-Tags hinzugefügt, Prozedurnamen korrigiert.

_________________
Prof.Y