DB2 7.2 Java UDF不在类路径中

l7mqbcuq  于 2022-11-07  发布在  DB2
关注(0)|答案(1)|浏览(162)

我创建了一个Java类,用Java实现LevenshteinDistance算法,以便在DB2 UDF中使用它。
显然,在DB2中,有两种注册java UDF的方法,一种是复制QIBM/UserData/OS 400/SQLLib/Function下的.class文件,另一种是复制一个JAR,然后使用SQLJ.INSTALL_JAR。
现在,我的Java源代码如下所示:

package FUNCTIONS;
public class LEVENSHTEIN {

public static int levenshteinDistance (String lhs, String rhs) {

    int len0 = lhs.length() + 1;                                                     
    int len1 = rhs.length() + 1;                                                     

    // the array of distances                                                       
    int[] cost = new int[len0];                                                     
    int[] newcost = new int[len0];                                                  

    // initial cost of skipping prefix in String s0                                 
    for (int i = 0; i < len0; i++) cost[i] = i;                                     

    // dynamically computing the array of distances                                  

    // transformation cost for each letter in s1                                    
    for (int j = 1; j < len1; j++) {                                                
        // initial cost of skipping prefix in String s1                             
        newcost[0] = j;                                                             

        // transformation cost for each letter in s0                                
        for(int i = 1; i < len0; i++) {                                             
            // matching current letters in both strings                             
            int match = (lhs.charAt(i - 1) == rhs.charAt(j - 1)) ? 0 : 1;             

            // computing cost for each transformation                               
            int cost_replace = cost[i - 1] + match;                                 
            int cost_insert  = cost[i] + 1;                                         
            int cost_delete  = newcost[i - 1] + 1;                                  

            // keep minimum cost                                                    
            newcost[i] = Math.min(Math.min(cost_insert, cost_delete), cost_replace);
        }                                                                           

        // swap cost/newcost arrays                                                 
        int[] swap = cost; cost = newcost; newcost = swap;                          
    }                                                                               

    // the distance is the cost for transforming all letters in both strings        
    return cost[len0 - 1];                                                          
}

}
在我最近读到的文档中,它说它必须遵守包结构,所以我把我的LEVENSHTEIN.class复制到了QIBM/UserData/OS 400/SQLLib/Function/FUNCTIONS下。还试着把它复制到Function下,以防我误解。
还创建了一个JAR并注册了它

CALL SQLJ.INSTALL_JAR('file:/QIBM/UserData/OS400/SQLLib/Function/testMain.jar','JARFUNCTIONS',0);

我尝试注册UDF的方法:

CREATE OR REPLACE FUNCTION DEBUG.LV( 
LHS VARCHAR(255) , 
RHS VARCHAR(255) ) 
RETURNS INTEGER   
LANGUAGE JAVA 
SPECIFIC DEBUG.LV 
NOT DETERMINISTIC 
READS SQL DATA 
CALLED ON NULL INPUT 
EXTERNAL NAME 'JARFUNCTIONS:FUNCTIONS.LEVENSHTEIN.levenshteinDistance' 
PARAMETER STYLE JAVA ; 

CREATE OR REPLACE FUNCTION DEBUG.LEVENSHTEIN( 
LHS VARCHAR(255) , 
RHS VARCHAR(255) ) 
RETURNS INTEGER   
LANGUAGE JAVA 
SPECIFIC DEBUG.LEVENSHTEIN 
NOT DETERMINISTIC 
READS SQL DATA 
CALLED ON NULL INPUT 
EXTERNAL NAME 'FUNCTIONS.LEVENSHTEIN.levenshteinDistance' 
PARAMETER STYLE JAVA ; 

CREATE OR REPLACE FUNCTION DEBUG.LEVENSHTEIN( 
LHS VARCHAR(255) , 
RHS VARCHAR(255) ) 
RETURNS INTEGER   
LANGUAGE JAVA 
SPECIFIC DEBUG.LEVENSHTEIN 
NOT DETERMINISTIC 
READS SQL DATA 
CALLED ON NULL INPUT 
EXTERNAL NAME 'LEVENSHTEIN.levenshteinDistance' 
PARAMETER STYLE JAVA ;

所有这些都告诉我,它无法在类路径下找到类,并确保.class编译文件位于/QIBM/UserData/OS 400/SQLLib/Function下,并且它实现了必要的接口,并且是公共的。
从我所读到的内容来看,使用JAVA风格的参数,我不需要扩展UDF。而且,我的db2_classes中的UDF是一个类而不是接口,所以我必须扩展它而不是实现它。我也试过这样做,没有什么变化。
也看到了这种宣告的风格,所以也试了一下:

CREATE OR REPLACE FUNCTION DEBUG.LEVENSHTEIN( 
LHS VARCHAR(255) , 
RHS VARCHAR(255) ) 
RETURNS INTEGER   
LANGUAGE JAVA 
SPECIFIC DEBUG.LEVENSHTEIN 
NOT DETERMINISTIC 
READS SQL DATA 
CALLED ON NULL INPUT 
EXTERNAL NAME 'LEVENSHTEIN!levenshteinDistance' 
PARAMETER STYLE JAVA ;

这一条告诉我,名称LEVENSHTEIN无法从外部名称LEVENSHTEIN!levenshteinDistance中识别出来,并且外部名称必须是package.subpackage.class.method
我在数据库的Security Administrator下,理论上我可以创建文件和文件夹(我在/Function下创建了一个文件夹,它确实被创建了)
我已经看了一打红皮书和参考书,尝试了不同的东西,以至于我甚至记不清我试过的所有东西。
任何帮助都是非常感谢的。谢谢
也尝试了一个空的构造函数,也扩展了UDF,并使用了一个调用super()的构造函数。

vwoqyblh

vwoqyblh1#

错误的java方法声明。您忘记了static修饰符。请参阅Java user-defined scalar functions主题。

参数样式Java

Java参数样式是由 SQLJ Part 1:SQL Routines 标准。编写Java UDF代码时,请使用以下约定。

  • Java方法必须是公共静态方法。
  • Java方法必须返回与SQL兼容的类型。返回值是方法的结果。
  • Java方法的参数必须是SQL兼容类型。
  • Java方法可以测试允许空值的Java类型的SQL NULL。

相关问题