【问题标题】:MySQL LevenshteinMySQL 编辑器
【发布时间】:2012-09-19 00:01:23
【问题描述】:

我正在尝试创建一个 MySQL 函数来计算 levenshtein 距离。我找到了一个看起来非常接近我需要的函数,但是它总是到处抛出错误——我是 MySQL 函数的新手,所以我不知道出了什么问题?

函数如下:

DELIMITER $$

CREATE FUNCTION LEVENSHTEIN( s1 CHAR(255), s2 CHAR(255)) 
RETURNS int(3) 
DETERMINISTIC
BEGIN
    DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
    DECLARE s1_char CHAR(255);
    DECLARE cv0, cv1 CHAR(255);

    SET s1_len = LENGTH(s1);
    SET s2_len = LENGTH(s2);
    SET cv1 = 0x00;
    SET j = 1;
    SET i = 1;
    SET c = 0;

    IF s1 = s2 THEN
        RETURN 0;
    ELSE IF s1_len = 0 THEN
        RETURN s2_len;
    ELSE IF s2_len = 0 THEN
        RETURN s1_len;
    ELSE
        WHILE j <= s2_len DO 
          SET c = c + 1; 
          IF s1_char = SUBSTRING(s2, j, 1) THEN  
            SET cost = 0; ELSE SET cost = 1; 
          END IF; 
          SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost; 
                SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
                IF c > c_temp THEN
                    SET c = c_temp;
                END IF;
                SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
            END WHILE;
            SET cv1 = cv0, i = i + 1;
        END WHILE;
    END IF;
    RETURN c;
END$$

DELIMITER ;

这是错误(到目前为止)。

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHILE; END IF; RETURN c; END' at line 36

编辑:原始代码可以在here找到

【问题讨论】:

  • 我将原始代码粘贴到 TOAD for MySQL 中,它运行完美。似乎不需要编辑。
  • 我只是做了同样的事情——在我试图让它工作的某个地方,我真的把代码搞砸了。添加分隔符后,代码运行良好。
  • 我正在尝试执行您的代码,但出现以下错误 1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 'WHILE; 附近使用的正确语法;万一;返回 c; END' 在第 36 行 为什么???

标签: mysql mysql5


【解决方案1】:

在创建函数之前不要忘记更改delimiter

DELIMITER $$

CREATE FUNCTION LEVENSHTEIN( s1 CHAR(255), s2 CHAR(255)) 
RETURNS int(3) 
DETERMINISTIC
BEGIN
    DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
    DECLARE s1_char CHAR(255);
    DECLARE cv0, cv1 CHAR(255);

    SET s1_len = LENGTH(s1);
    SET s2_len = LENGTH(s2);
    SET cv1 = 0x00;
    SET j = 1;
    SET i = 1;
    SET c = 0;

    IF s1 = s2 THEN
        RETURN 0;
    ELSE IF s1_len = 0 THEN
        RETURN s2_len;
    ELSE IF s2_len = 0 THEN
        RETURN s1_len;
    ELSE
        WHILE j <= s2_len DO 
          SET c = c + 1; 
          IF s1_char = SUBSTRING(s2, j, 1) THEN  
            SET cost = 0; ELSE SET cost = 1; 
          END IF; 
          SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost; 
                SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
                IF c > c_temp THEN
                    SET c = c_temp;
                END IF;
                SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
            END WHILE;
            SET cv1 = cv0, i = i + 1;
        END WHILE;
    END IF;
    RETURN c;
END$$

DELIMITER ;

【讨论】:

  • 运行代码后,根本没有输出——没有错误,没有成功。当我尝试SELECT LEVENSHTEIN('hello','hello!') 时,数据库中不存在实际函数
  • @Shane 请注意查询末尾的END$$。再试一次。
  • 查看“WHILE j c_temp”部分:有明显的复制粘贴错误。使用原始代码并使用合适的 IDE(例如 TOAD for MySQL 或 AquaData Studio)
  • @Shane 你的代码做得很好,只是将它粘贴到我的服务器上并且没有返回错误。
  • 你好。我尝试了代码,但仍然没有输出 - 没有错误,没有成功。我错过了什么?
【解决方案2】:

这对我来说很好用

DELIMITER $$
CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255) )
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
DECLARE s1_char CHAR;
-- max strlen=255
DECLARE cv0, cv1 VARBINARY(256);
SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
IF s1 = s2 THEN
RETURN 0;
ELSEIF s1_len = 0 THEN
RETURN s2_len;
ELSEIF s2_len = 0 THEN
RETURN s1_len;
ELSE
WHILE j <= s2_len DO
SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
END WHILE;
WHILE i <= s1_len DO
SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
WHILE j <= s2_len DO
SET c = c + 1;
IF s1_char = SUBSTRING(s2, j, 1) THEN
SET cost = 0; ELSE SET cost = 1;
END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
IF c > c_temp THEN SET c = c_temp; END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
IF c > c_temp THEN
SET c = c_temp;
END IF;
SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
END WHILE;
SET cv1 = cv0, i = i + 1;
END WHILE;
END IF;
RETURN c;
END$$
DELIMITER ;

【讨论】:

    【解决方案3】:

    您忘记了语句分隔符“;”几乎在每一行的末尾。

    【讨论】:

    • DocJones,我删除了它,因为它似乎会导致更多错误......我现在就试一试。
    • 在我看来,这显然是从一些伪代码中复制而来的,并不是真正正确的 mysql 语法。 WHILE 循环看起来也很奇怪。我去看看
    • MySQL代码在我得到它之前......这很可能是我的错误。我会找到它的链接...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多