如何在 mysql 的 UDF 中创建两个循环
Posted
技术标签:
【中文标题】如何在 mysql 的 UDF 中创建两个循环【英文标题】:How to make TWO loops in a UDF at mysql 【发布时间】:2020-04-18 09:03:08 【问题描述】:类似于***Posting 我想计算由TITLE1 和TITLE2 组成的m x n
矩阵的Levenshtein 距离。
我的 Levenshtein Functions 工作正常,来自这里:LD
但我的问题是如何在 UDF 中循环遍历 m x n
?
结果应该是一个包含m x n
行的表,其中包含 LD、TITLE1 和 TITLE2。
我已经这样做了 - 但我总是出错
1338 Cursor Declaration after Handler Declaration
我的 UDF 如下所示:
BEGIN
DECLARE bDone INT;
DECLARE bDone1 INT;
DECLARE var2 varCHAR(255); -- or approriate type
DECLARE Var1 INT;
DECLARE c1Var1 VARCHAR(250);
DECLARE curs CURSOR FOR SELECT recid as BIOTIrecid, replace(replace(BIOGRAPHYTITLE," [in SCOPUS]",""),"[SIMILAR]","") as bioti FROM BIO ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
DECLARE curs1 CURSOR FOR SELECT trim(concat(scopus.Titel," ",scopus.Untertitel)) as scopusti FROM scopus ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
DROP TABLE IF EXISTS LDResults;
CREATE TABLE `LDResults` (
`BIOGRAPHYTITLE` varchar(255) DEFAULT NULL,
`recid` int(11) NOT NULL AUTO_INCREMENT,
`BIOTIrecid` int(11) default NULL,
`LD` varchar(255) DEFAULT NULL,
`ScopusTI` varchar(255) DEFAULT NULL,
PRIMARY KEY (`recid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
OPEN curs1;
SET bDone1 = 0;
#---------------- run all rows for scopusti
REPEAT
FETCH curs1 into c1var1;
#-----------------------------------------
OPEN curs;
SET bDone = 0;
#----- run all COLUMNs for biographytitle
REPEAT
FETCH curs INTO var1, var2;
INSERT INTO LDResults (`BIOGRAPHYTITLE`, `BIOTIrecid`, `LD`, `ScopusTI`) VALUES (var2, var1, LEVENSHTEIN(var2,c1var1), c1var1);
UNTIL bDone END REPEAT;
#--------------------------------------------
CLOSE curs;
UNTIL bDone1 END REPEAT;
CLOSE curs1;
SELECT * FROM LDResults;
END
我解决这个问题的方法是复杂的,还是可以通过更快更好的解决方案来完成?
感谢所有建议。
编辑: 我可以在这里使用柜台:任何 cmets?
BEGIN
-- DECLARE bDone INT;
-- DECLARE bDone1 INT;
DECLARE i INT;
DECLARE var2 varCHAR(255); -- or approriate type
DECLARE Var1 INT;
DECLARE cVar1 VARCHAR(250);
DECLARE curs1 CURSOR FOR SELECT trim(concat(t.Titel," ",t.Untertitel)) as scopusti FROM tscopus t ;
DECLARE curs CURSOR FOR SELECT recid as BIOTIrecid, replace(replace(BIOGRAPHYTITLE," [in SCOPUS]",""),"[SIMILAR]","") as bioti FROM tBIO ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
#DECLARE curs1 CURSOR FOR SELECT trim(concat(t.Titel," ",t.Untertitel)) as scopusti FROM tscopus t ;
#DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
DROP TABLE IF EXISTS LDResults;
CREATE TABLE `LDResults` (
`BIOGRAPHYTITLE` varchar(255) DEFAULT NULL,
`recid` int(11) NOT NULL AUTO_INCREMENT,
`BIOTIrecid` int(11) default NULL,
`LD` varchar(255) DEFAULT NULL,
`ScopusTI` varchar(255) DEFAULT NULL,
PRIMARY KEY (`recid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
OPEN curs1;
SET i = 0;
SET bDone1 = 0;
-- ---------------- run all rows for scopusti
REPEAT
FETCH curs1 into cvar1;
set i=(i+1);
-- -----------------------------------------
OPEN curs;
SET bDone = 0;
-- ----- run all COLUMNs for biographytitle
REPEAT
FETCH curs INTO var1, var2;
INSERT INTO LDResults (`BIOGRAPHYTITLE`, `BIOTIrecid`, `LD`, `ScopusTI`) VALUES (var2, var1, LEVENSHTEIN(var2,cvar1), cvar1);
UNTIL bDone END REPEAT;
-- --------------------------------------------
CLOSE curs;
UNTIL (i >= 2) END REPEAT;
CLOSE curs1;
SELECT * FROM LDResults;
END
【问题讨论】:
【参考方案1】:我的意思是你可以通过下一个方法使用 CROSS JOIN 在你的代码中没有循环。 CROSS JOIN 按定义返回两个表行结果的乘积。 因此,您可以使用此结果,并在进行一些数据操作后将结果插入到新表中,例如:
DROP TABLE IF EXISTS LDResults;
CREATE TABLE `LDResults` (
`BIOGRAPHYTITLE` varchar(255) DEFAULT NULL,
`recid` int(11) NOT NULL AUTO_INCREMENT,
`BIOTIrecid` int(11) default NULL,
`LD` varchar(255) DEFAULT NULL,
`ScopusTI` varchar(255) DEFAULT NULL,
PRIMARY KEY (`recid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO LDResults (`BIOGRAPHYTITLE`, `BIOTIrecid`, `LD`, `ScopusTI`)
SELECT bioti, BIOTIrecid, LEVENSHTEIN(bioti,scopusti), scopusti
FROM (
SELECT
replace(replace(BIO.BIOGRAPHYTITLE," [in SCOPUS]",""),"[SIMILAR]","") as bioti,
BIO.recid as BIOTIrecid,
trim(concat(scopus.Titel," ",scopus.Untertitel)) as scopusti
FROM scopus
CROSS JOIN BIO
) tbl;
【讨论】:
以上是关于如何在 mysql 的 UDF 中创建两个循环的主要内容,如果未能解决你的问题,请参考以下文章
在 for 循环中使用 udf 在 Pyspark 中创建多个列