Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
Database Servers
DB2InformixIngresMS SQLOraclePervasive.SQLPostgreSQLProgressSybase
Desktop Databases
FileMakerFoxProMS AccessParadox
General
General DB TopicsDatabase Theory
Related Topics
Java Development.NET DevelopmentVB DevelopmentMore Topics ...

Database Forum / DB2 Topics / September 2005

Tip: Looking for answers? Try searching our database.

Do I observe the DB2GENERAL calling convention in my Java UDF?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
claus.hirth@abraxas.ch - 28 Sep 2005 10:18 GMT
If I create the function HELLO in schema S01 as follows,

@
CREATE FUNCTION S01.HELLO()
RETURNS VARCHAR(32)
EXTERNAL NAME 'UDFSRVXYZ!sayHelloWorld'
LANGUAGE JAVA
PARAMETER STYLE DB2GENERAL
NO SQL
DETERMINISTIC
NOT FENCED
SCRATCHPAD
NO EXTERNAL ACTION
@

then I can implement it as shown here?

// Default package
public
class UDFSRVXYZ
extends
    COM.ibm.db2.app.UDF
{
    public
    void sayHelloWorld()
    throws
        Exception
    {
        set(1, "Hello, World!" );
    }
}

I tried hard, but I could not get it to work.
What I already took care about:

(1) Deploy class file to the FUNCTION directory of the instance. In my
case that is C:\Programme\IBM\SQLLIB\FUNCTION\ on the server machine.
(2) issue the CREATE FUNCTION statement as shown above
(3) CALL SQLJ.REFRESH_CLASSES()
(4) I do have EXECUTE permission on S01.HELLO
Then I wanted to reap the results:

SELECT S01.HELLO(), value FROM S01.HELLOTABLE FETCH FIRST 3 ROWS ONLY

But that resulted in DB2 complaining, and not executing the Java method
I wanted it to execute:

SQL4306N  In Java gespeicherte Prozedur oder benutzerdefinierte
Funktion
"S01.HELLO", spezifischer Name "SQL050928105824200" kann die
Java-Methode
"sayHelloWorld", Kennung "(Ljava/lang/String;)V" nicht aufrufen.
SQLSTATE=42724

So now, which part of the manual did I neglect to pay attention to? I
think I did observe the calling convention for DB2GENERAL. Another
question would be what the Java method should look like with parameter
style JAVA?

Any help much appreciated, Claus

----

A complete transcript is enclosed so you can see exactly what I did:

------------------------------ Eingegebene Befehle
---------------------------

DROP FUNCTION S01.HELLO
@
CREATE FUNCTION S01.HELLO()
RETURNS VARCHAR(32)
EXTERNAL NAME 'UDFSRVXYZ!sayHelloWorld'
LANGUAGE JAVA
PARAMETER STYLE DB2GENERAL
NO SQL
DETERMINISTIC
NOT FENCED
SCRATCHPAD
NO EXTERNAL ACTION
@
CALL SQLJ.REFRESH_CLASSES()
@
DROP TABLE S01.HELLOTABLE
@
CREATE TABLE S01.HELLOTABLE ( value INTEGER )
@
INSERT INTO S01.HELLOTABLE ( value ) VALUES ( 1 )
@
INSERT INTO S01.HELLOTABLE ( value ) VALUES ( 2 )
@
INSERT INTO S01.HELLOTABLE ( value ) VALUES ( 3 )
@
SELECT value FROM S01.HELLOTABLE
FETCH FIRST 3 ROWS ONLY
@
SELECT S01.HELLO(), value FROM S01.HELLOTABLE
FETCH FIRST 3 ROWS ONLY
@
------------------------------------------------------------------------------
DROP FUNCTION S01.HELLO
DB20000I  Der Befehl SQL wurde erfolgreich ausgeführt.

CREATE FUNCTION S01.HELLO()
RETURNS VARCHAR(32)
EXTERNAL NAME 'UDFSRVXYZ!sayHelloWorld'
LANGUAGE JAVA
PARAMETER STYLE DB2GENERAL
NO SQL
DETERMINISTIC
NOT FENCED
SCRATCHPAD
NO EXTERNAL ACTION

DB20000I  Der Befehl SQL wurde erfolgreich ausgeführt.

CALL SQLJ.REFRESH_CLASSES()
DB20000I  Der Befehl CALL wurde erfolgreich ausgeführt.

DROP TABLE S01.HELLOTABLE
DB20000I  Der Befehl SQL wurde erfolgreich ausgeführt.

CREATE TABLE S01.HELLOTABLE ( value INTEGER )
DB20000I  Der Befehl SQL wurde erfolgreich ausgeführt.

INSERT INTO S01.HELLOTABLE ( value ) VALUES ( 1 )
DB20000I  Der Befehl SQL wurde erfolgreich ausgeführt.

INSERT INTO S01.HELLOTABLE ( value ) VALUES ( 2 )
DB20000I  Der Befehl SQL wurde erfolgreich ausgeführt.

INSERT INTO S01.HELLOTABLE ( value ) VALUES ( 3 )
DB20000I  Der Befehl SQL wurde erfolgreich ausgeführt.

SELECT value FROM S01.HELLOTABLE FETCH FIRST 3 ROWS ONLY

VALUE
-----------
         1
         2
         3

 3 Satz/Sätze ausgewählt.

SELECT S01.HELLO(), value FROM S01.HELLOTABLE FETCH FIRST 3 ROWS ONLY

1                                VALUE
-------------------------------- -----------
SQL4306N  In Java gespeicherte Prozedur oder benutzerdefinierte
Funktion
"S01.HELLO", spezifischer Name "SQL050928110204800" kann die
Java-Methode
"sayHelloWorld", Kennung "(Ljava/lang/String;)V" nicht aufrufen.
SQLSTATE=42724

SQL4306N  In Java gespeicherte Prozedur oder benutzerdefinierte
Funktion "S01.HELLO", spezifischer Name "SQL050928110204800" kann die
Java-Methode "sayHelloWorld", Kennung "(Ljava/lang/String;)V      "
nicht aufrufen.

Erklärung:

Die mit der Klausel EXTERNAL NAME einer Anweisung CREATE
PROCEDURE oder CREATE FUNCTION bezeichnete Java-Methode konnte
nicht gefunden werden. Die deklarierte Argumentenliste stimmt
möglicherweise nicht mit den von der Datenbank erwarteten Angaben
überein, oder das Exemplar verfügt nicht über eine allgemein
bekannte ("public") Methode.

Benutzeraktion:

Stellen Sie sicher, dass für das Exemplar die Java-Methode als
allgemein bekannt ("public") deklariert ist und die erforderliche
Argumentenliste für den Aufruf zur Verfügung steht.

sqlcode :  -4306

sqlstate : 42724

----
claus.hirth@abraxas.ch - 28 Sep 2005 12:43 GMT
Is it possible to extract a candidate Java method signature from what's
in the SYSCAT.FUNC*-Tables? Anyone done that already, ie anyone has
already written a UDF that will spit out a matching method signature in
return for schema name and function name?

What is SYSPROC.GET_ROUTINE_OPTS() about?
Serge Rielau - 28 Sep 2005 13:54 GMT
> Is it possible to extract a candidate Java method signature from what's
> in the SYSCAT.FUNC*-Tables? Anyone done that already, ie anyone has
> already written a UDF that will spit out a matching method signature in
> return for schema name and function name?
>
> What is SYSPROC.GET_ROUTINE_OPTS() about?

It's... SET_ROUTINE_OPTS() best friend.... ;-)
The routine options are used to set the PREP options for _SQL_ Procedures.
Common settings are: 'BLOCKING ALL' or 'EXPLAIN ALL'

Signature

Serge Rielau
DB2 SQL Compiler Development
IBM Toronto Lab

claus.hirth@abraxas.ch - 28 Sep 2005 14:42 GMT
I see. And what about my original post?
4.spam@mail.ru - 29 Sep 2005 06:48 GMT
Hello.

You have to do this:
public void sayHelloWorld(String result)
instead of:
public void sayHelloWorld()

and don't use this clauses in the function definition:
NOT FENCED
SCRATCHPAD

Sincerely,
Mark B.
claus.hirth@abraxas.ch - 29 Sep 2005 13:29 GMT
.

Adding the String argument to the method signature solved the problem,
thank you.

For the rest of you that might be interested:

* Specifying SCRATCHPAD or not had no influence on whether or not the
function is called correctly. But it is advantageous not to specify
SCRATCHPAD for this UDF, as it doesn't need to use a scratchpad.

* Specifying NOT FENCED works -- if only you deploy the code into the
proper subdirectory, as specified in the manuals. Thanks Mark, I
overlooked that, looking at it so many times.

Kind regards, Claus
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.