我创建了一个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()的构造函数。
1条答案
按热度按时间vwoqyblh1#
错误的java方法声明。您忘记了
static
修饰符。请参阅Java user-defined scalar functions主题。参数样式Java
Java参数样式是由 SQLJ Part 1:SQL Routines 标准。编写Java UDF代码时,请使用以下约定。