Announcement

Collapse
No announcement yet.

UDFs in Interbase (an Hr.Andreas Kosch)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • UDFs in Interbase (an Hr.Andreas Kosch)

    An Herrn Andreas Kosch

    Ich habe Ihre UDF betreffend Soundex aus Ihrem Buch Client/Server bei der Datenbank angemeldet. Der SQL-Explorer zeigt, daß die Funktionen korrekt übernommen wurden.

    Trotzdem erhalte ich bei "Select oslower(Name) from TabXX" die Meldung "Allgemeiner SQL-Fehler A fatal exception occured during the execution of a user defined function. arithmetic exception, numeric overflow, or string truncation."

    Name ist hier VarChar(30).

    Was habe ich falsch gemacht ?

    Kann man auch längere oder kürzere Felder der Function Oslower (welche mit Länge 40) deklariert ist, übergeben ? Detto bei Soundex.

    Die Funktion wurde übrigens nicht mit einem SQL-Script sondern mit einer TQuery-Instanz wie folgt bei der Datenbank angemeldet:

    with Query1 do<p>
    begin<p>
    SQL.Clear;<p>
    SQL.Add('DECLARE EXTERNAL FUNCTION OSLOWER CHAR(40) ');<p>
    SQL.Add('RETURNS CHAR(40) ');<p>
    SQL.Add('ENTRY_POINT "OSLOWER" MODULE_NAME "OSUDF5.DLL"');<p>
    ExecuteSQL;<p>
    end;<p>

    Detto die anderen Funktionen.

    Bitte geben Sie mir Ihre Antwort per EMail "[email protected]"

    Vielen Dank!<p>
    Helmut

  • #2
    Nachtrag:

    Ich möchte die Länge des Soundex-Strings auf 80 erhöhen. Was muss man alles beachten ?

    Helmu

    Comment


    • #3
      2.Nachtrag:

      Wenn die Interbase-Datenbank auf einem Server liegt und von einer Workstation abgefragt wird, wo müssen dann die UDF.Dll's liegen, auf dem Server, der Workstation oder beides ?

      Zum Thema Soundex:<p>
      Stimmt es, daß man für die Interbase UDF eine eigene DLL creiert und zusätzlich eine eigene Unit (Soundex aus dem Demo-Verzeichnis) zum Ansprechen der Function Soundex in Pascal, in welcher die gleiche Function 1:1 nochmal aufgeführt wird ?

      Helmu

      Comment


      • #4
        Hallo,

        die UDF-Funktion OSLOWER wurde im Kommentarblock als "Sonderfall" bezeichnet:
        <pre>
        { Sonderfall:
        Die über einen PChar als Referenz übergebene Zeichenkette
        wird in Kleinbuchstaben konvertiert und zurückgeliefert.
        Da in der DLL kein Speicherplatz angefordert wird, muß die
        UDF-Funktion nicht mit dem Schlüsselwort FREE_IT gekennzeichnet
        werden. }

        function OSLOWER(pInput : PChar): PChar; cdecl;
        begin
        try
        Result := StrLower(pInput);
        except
        Result := '';
        end;
        end;
        </pre>
        Leider steht dieser Weg (der in der Version 5.1 funktioniert) ab der Version 5.5 nicht mehr so zur Verfügung, so dass OSLOWER genauso neu implementiert werden sollte wie die beiden anderen Funktionen (OSSOUNDEX oder OSSOUNDEX2). Da hier mit FREE_IT gearbeitet wird, kann der Speicherbereich in der UDF-Funktion je nach Bedarf angefordert werden, so dass eine Anpassung an die benötigte Spaltenbreite möglich ist.

        zur Frage 2: <br>
        Da in der UDF-Funktion der Parameter über StrPas umkopiert wird und die Output-Grösse gleich bleibt, muss nur die UDF-Deklaration in der Datenbank angepasst werden.

        zum 2. Nachtrag: <br>
        Die UDF-DLL muss auf dem Server-Rechner in einem Suchpfad-Verzeichnis liegen. Am sichersten ist es, wenn die DLL in das <b>Bin</b>-Unterverzeichnis vom InterBase kopiert wird (in diesem Fall wird die DLL immer gefunden).

        zur letzten Fragen: <br>
        Wenn die Soundex-Funktion nur in der Datenbank (UDF) benötigt wird, ist keine Pascal-Unit für das Anwendungsprogramm des Clients notwendig. Wenn im Programm jedoch zum Beispiel der Soundex-Code ebenfalls berechnet werden soll (zum Beispiel bei einer Suche nach einem Wert in der Soundex-Spalte der Tabelle ohne Aufruf der UDF), wird diese Implementierungs-Unit (als 1:1-Kopie der UDF-Funktion) benötigt

        Comment


        • #5
          Hallo,

          vielen Dank Hr.Kosch für die Beantwortung.

          Ich vergaß zu erwähnen, daß keine der UDF-Funktionen, oslower, ossoundex und ossoundex2 anwendbar ist. Bei allen tritt die Meldung
          <b>"Allgemeiner SQL-Fehler A fatal exception occured during the execution of a user defined function. arithmetic exception, numeric overflow, or string truncation."</b> auf, sobald der Insert-Trigger aktiv wird (Einfüllen von Daten in die Tabelle).

          Ich habe bisher folgendes versucht:

          a) ich habe die Funktion "ib_util_malloc" statt "malloc" verwendet.
          (Hiezu musste noch die DLL "ib_util.dll" aus dem Lib- in das Bin-Verzeichnis von Interbase kopiert werden).
          <b>Keine Abhilfe</b>

          b) ich habe z.B. die Funktion "oslower" so umgestellt, daß sie Speicher allociert und Interbase diesen per FREE_IT freigibt und auch die Deklaration der UDF entsprechend umgestellt.
          <b>Keine Abhilfe</b>

          c) ich habe den Typ CSTRING verwendet.
          <b>Keine Abhilfe</b>

          Sobald der Insert-Trigger z.B. die Funktion "New.ZunameSdx = OsSoundex2(New.Zuname)" aufruft, erscheint diese Meldung. Die Variablen sind alle korrekt deklariert. Wenn statt dem Funktionsergebnis von ossoundex2 ein Fixwert zugewiesen wird (New.ZunameSdx = "ggggg" o.a.), funktioniert der Trigger ohne Fehlermeldung.

          Die Meldung wird also durch den Aufruf von OSSOUNDEX2 verursacht. das gleiche gilt für die anderen Funktionen, wie OSLOWER usw.

          Der SQL-Monitor meldet hiebei: Unmapped SQL Error Code: -901

          Es scheint so, daß keine der exportierten UDF-Funktionen anwendbar ist.

          Haben Sie eine Lösung dafür ? Ich würde diese dringend brauchen. Auch ist diese wichtig, für allfällige weitere UDF's.

          Danke für Ihre Bemühungen<br>
          Helmu

          Comment


          • #6
            Nachtrag:

            Ist es möglich, daß die Funktion durch den Aufruf "New.ZunameSdx = OsSoundex2(New.Zuname)" den Stringparameter in falscher Form erhält ?

            OsSoundex2 erwartet ja einen pChar. Gibt es eine UDF- (oder Interbase)Umwandlungsfunktion mit welcher man einen "Stringwert" in einen pChar" umwandeln kann und auch gegensinnig (für das Ergebnis) ?

            z.B. "New.ZunameSdx = WandlungVonPCharInString(OsSoundex2( WandlungVonStringInPChar(New.Zuname)))"

            Helmu

            Comment


            • #7
              Hallo,

              welche InterBase-Version wird verwendet? Um zu prüfen, ob die Installation/Registrierung in Ordnung ist, würde ich den im Buch verwendeten Aufruf ausprobieren (Datenbank Udfdb.gdb):
              <pre>
              SELECT OSSOUNDEX2(Vorname) FROM KUNDEN
              </pre>
              In diesem Fall sollte im SQL-Explorer bzw. in WISQL anstelle des Vornamens der Soundex-Wert zurückgeliefert werden

              Comment


              • #8
                Hallo,

                Es wird Interbase 5.6 unter Windows-2000 Profess. (Server u. Workstation) verwendet.

                Beim Austesten mit WISQL sah ich, daß die UDF-Funktionen auch dort nicht funktionieren.

                Ich habe dann entdeckt, daß der bei Deklaration mit einer TQuery der letzte Befehl ... MODULE_NAME "OSUDF5.DLL";' mit einem Strichpunkt abgeschlossen sein muß !

                Jetzt funktioniert OSLOWER und OSDAYSADD. OSSOUNDEX und OSOUNDEX2 geht jedoch immer noch nicht. Die Funktionen sind Original wie in Ihrem Buch. Ich habe nur die Länge von 40 auf 80 erhöht. (Es geht auch nicht mit 40). Obwohl auch hier der Strichpunkt ist, produzieren diese beiden Funktionen bei Aufruf in einem SQL-Statement im Programm sowohl auch in WISQL obigen Fehler.

                Ich habe dann versucht, die Funktionen der OSUDF5.DLL in einem Pascal-Programm zu testen, indem ich die Funktion z.B. exportieren wollte:

                function OsSoundex2( pSourceChar ) : pChar; <b>stdcall external "S:\OSUDF5.DLL"; </b>

                Es erscheint die Meldung "Der Prozedureinsprungpunkt "OsSoundex2" wurde in der DLL "S:\OSUDF5.DLL" nicht gefunden".

                Kann man diese Funktionen (in einer DLL) in einem Pascal-Programm testen ?

                Die Pascal-Unit "Soundex" mit einer 1:1 Prozedur funktioniert.

                Helmu

                Comment


                • #9
                  Nachtrag:

                  Ich habe auch versucht die UDF-Funktionen mit einem SQL-Script bei der Datenbank anzulegen (mit WISQL). Es funktionieren wieder OSLOWER und OSDAYSADD.

                  OSSOUNDEX und OSSOUNDEX2 liefern wieder vorgenannten Fehler. Ich vermute, daß von den 3 geschilderten Fehlermöglichkeiten, der Fehler "string truncation" zuständig ist.

                  Zur Information: ich habe OsLower auf Speicherallokierung mit ib_util_malloc umgestellt, samt Free_It in der Deklaration. Die Länge ist 255. Diese Funktion arbeitet daher nach dem "gleichen" Prinzip wie OsSoundex2. Dort ist die Länge 80. Wieso geht es dort nicht ? Die Prozeduren OsLower und OsSoundex2 unterscheiden sich nur in der Zeile

                  OsLower: S := StrPas(StrLower(pInput)); // S:String<br>
                  OsSoundex2: sSnd := SoundexCode(StrPas(pSource)); // sSnd:String

                  und sind sonst absolut identisch!

                  Helmut

                  Helmu

                  Comment


                  • #10
                    Hallo,

                    ich habe den InterBase 5.6 nur noch auf einer NT4-Maschine (aber nicht auf Windows 2000). Der folgende Test ist bei mir erfolgreich: <br>
                    1. Datei UDFDB.GDB von der Buch-CDROM auf die Festplatte kopieren. <br>
                    2. Schreibschutz-Attribut von UDFDB.GDB entfernen <br>
                    3. OSUDF5.DPR von der Buch-CDROM neu compilieren, DLL in das BIN-Verzeichnis des InterBase kopieren.<br>
                    4. SQL-Explorer starten, Alias für UDFDB.GDB mit WEurope ANSI-Zeichensatz anlegen. <br>
                    5. Datenbank im SQL-Explorer öffnen, die UDF-Funktionen sind bereits vorhanden. <br>
                    6. SELECT-Abfrage <i>SELECT OSSOUNDEX(Vorname) FROM KUNDEN</i> starten, die Soundex-Werte werden angezeigt. <br>
                    7. SELECT-Abfrage <i>SELECT OSSOUNDEX2(Vorname) FROM KUNDEN</i> starten, die Soundex-Werte werden angezeigt.<br>
                    8. SELECT-Abfrage <i>SELECT OSLOWER(Vorname) FROM KUNDEN</i> liefert beim InterBase 5.6 (im Gegensatz zum 5.1) nur die o.g. Fehlermeldung zurück.

                    Wenn hier im Schritt 6/7 eine Fehlermeldung kommt, ist die DLL oder eine der abhängigen DLLs nicht im Suchpfad des InterBase. In diesem Fall würde ich die DLLs aus dem <b>Lib</b>-Unterverzeichnis sowie die OSUDF5.DLL in das <b>Bin</b>-Verzeichnis des InterBase kopieren. Die Microsoft-DLL <b>MSVCRT.DLL</b> sollte die Versionsnummer 6.0.xxxx.x haben.

                    P.S: Wenn die in der DLL exportierte Funktion nicht über den Index, sondern über den Namen angesprochen wird, muss die exakte Schreibweise wie im <b>Exports</b>-Abschnitt verwendet werden.
                    &#10

                    Comment


                    • #11
                      Hallo,

                      vielen Dank Herr Kosch für Ihre Bemühungen.

                      Ich habe lt.Ihrem Vorschlag mit dem SQL-Explorer getestet:

                      Alle: Window-2000 Profess., Delphi 5 Enterprise (Update #1)

                      Verwendet wurde Ihre DLL "OSUDF5.DLL":

                      Datenbank Lokal Datenbank auf Server
                      UDFDB.GDB (Kosch) HVW.GDB (Zmaritsch)

                      oslower Fehler OK.
                      ossoundex OK. Fehler
                      ossoundex2 OK. Fehler
                      osdaysadd -- OK.

                      Die gleichen Ergebnisse treten auf, egal ob ich "Ihre" DLL OSUDF5.DLL oder meine abgeänderte DLL OSUDF5.DLL verwende. Es wurden jeweils die Units auf dem Server als auch lokal ausgetauscht.

                      Ich habe Ihre Original-DLL aus dem Buch (nachkompiliert) sowohl auf dem Server als auch lokal getestet. Das Ergebnis ist in beiden Fällen dasselbe.

                      Ich habe die UDF-Funktionen in meiner Datenbank mit einer TQUERY angemeldet.

                      Der Alias wurde jeweils mit dem Treiber "WUeurope ANSI" als auch mit "Borland DEU-Latin1" getestet. Ergibt gleiches Verhalten.

                      Ich kann mir keinen Reim aus den Ergebnissen machen. Die Tatsache, daß die beiden Funktionen OsSoundex mit Ihrer Datenbank funktionieren, heißt einmal daß sie grundsätzlich unter Windows-2000 laufen. Aber warum produzieren diese Funktionen einen Fehler in meiner Datenbank ?

                      Die Funktion Oslower, welche bei mir funktioniert und bei Ihnen nicht, habe ich wie schon erwähnt, auf Speicherallokierung und FREE_IT umgestellt.

                      Ich habe auch die Funktionen aus meiner Original-UDF-DLL exportiert und in Pascal aufgerufen. Dort funktionieren sie.

                      MSVCRT.DLL hat eine Version größer als 6.1.xxxx

                      Mich stört, daß die Funktionen Oslower und OsSoundex2 "fast identisch" sind. Kann es sein, daß die unterschiedlichen Rückgabegrößen den Fehler in SQL auslösen ?

                      Ich hoffe, daß ich mit Ihrer geschätzten Hilfe das Problem lösen kann.

                      Helmu

                      Comment


                      • #12
                        Nachtrag: Tabelle formatiert

                        <pre>
                        Alle: Window-2000 Profess., Delphi 5 Enterprise (Update #1)

                        Verwendet wurde Ihre DLL "OSUDF5.DLL":

                        Datenbank Lokal Datenbank auf Server
                        UDFDB.GDB (Kosch) HVW.GDB (Zmaritsch)

                        oslower Fehler OK.
                        ossoundex OK. Fehler
                        ossoundex2 OK. Fehler
                        osdaysadd -- OK.

                        </pre&gt

                        Comment


                        • #13
                          DIE LÖSUNG:

                          Das Resultat von OSSOUNDEX ist in der Deklaration DECLARE ... auf CHAR(6) und von OSSOUNDEX auf CSTRING(6) zu setzen.

                          Dann funktionieren die UDF's auch unter Interbase 5.6 und Windows-2000.

                          In der Pascal-Unit "Soundex.pas" im Verzeichnis DEMO ist Soundex-Len von 4 auf 5 zu setzen (falls diese Funktion auch unter Pascal benötigt wird).

                          Helmu

                          Comment

                          Working...
                          X