phpMyAdmin - mariaDB 罗马数字功能

phpMyAdmin - mariaDB roman numerals function

任何人都可以帮助我使用我的排序功能 - 说真的,我不知道如何让它按预期工作。 :( 数据库在 Xampp 的 MariaDB 中。我使用 phpMyAdmin 来执行查询。

DELIMITER $$

DROP FUNCTION IF EXISTS convRomanNumeral$$

CREATE FUNCTION convRomanNumeral (numeral CHAR(4))
  RETURNS INT
BEGIN
  DECLARE intnum INT;
    CASE numeral
      WHEN "I" THEN intnum = 1;
      WHEN "II" THEN intnum = 2;
    END CASE;
  RETURN intnum;
END;

$$

SET @iteration = -1;

UPDATE `st0gk_docman_documents` 
    SET created_on = DATE('2016-06-14') + INTERVAL(@iteration := @iteration + 1) SECOND
    WHERE `docman_category_id` = 141 ORDER BY convRomanNumeral(SUBSTRING(SUBSTRING_INDEX(title,'/',1),' ',-2) ASC, SUBSTRING_INDEX(title,'/',-2)+0 ASC;

所以我想实现的是按标题对文档进行排序。示例标题是:

按第一个罗马数字然后按第二个阿拉伯数字对它们进行排序后,我想更新日期。以下仅按第二个阿拉伯数字更新的代码可以正常工作:

SET @iteration = -1;

UPDATE `st0gk_docman_documents` 
    SET created_on = DATE('2016-06-14') + INTERVAL(@iteration := @iteration + 1) SECOND
    WHERE `docman_category_id` = 141 ORDER BY SUBSTRING_INDEX(title,'/',-2)+0 ASC;

我想使用 CASE 来 return 罗马值的适当变量。我知道它并不完美,但我什至无法使 CASE 和 FUNCTION 工作。我做错了什么?欢迎所有建议。

执行此操作的最佳方法是添加另一列,该列具有与该字符串等效的 sortable。并在 插入 table.

之前使用非 SQL 代码解析和构建该列

我犯的第一个错误是试图立即执行整个查询...在排除第一个小屋后,调试似乎变得更简单了。 :D

所以我创建了 case 函数来转换罗马数字:

DELIMITER $$

DROP FUNCTION IF EXISTS convRomanNumeralSubFunction$$
CREATE FUNCTION convRomanNumeralSubFunction (numeral CHAR(1))
  RETURNS INT
BEGIN
  DECLARE intnum INT;
    CASE numeral
      WHEN "I" THEN SELECT 1 INTO intnum;
      WHEN "X" THEN SELECT 10 INTO intnum;
      WHEN "C" THEN SELECT 100 INTO intnum;
      WHEN "M" THEN SELECT 1000 INTO intnum;
      WHEN "V" THEN SELECT 5 INTO intnum;
      WHEN "L" THEN SELECT 50 INTO intnum;
      WHEN "D" THEN SELECT 500 INTO intnum;
    END CASE;
  RETURN intnum;
END;

$$

之后我声明了转换所需的第二个函数。我不知道你是否可以在函数内部声明函数......我不想在这上面浪费更多时间。当然,您可以在过程中声明函数。无论如何。警告:此函数不是像 IIX 这样的 BAD 数字的证明。像这样的数字或将被错误地计算。 AXI也不算。

DELIMITER $$

DROP FUNCTION IF EXISTS convRomanNumeral$$
CREATE FUNCTION convRomanNumeral (numeral CHAR(10))
  RETURNS INT
BEGIN
  DECLARE currentintnum, previntnum, intnum, counter, numerallength INT;
  SET numerallength = LENGTH(numeral);
  SET counter = numerallength;
  SET intnum = 0;
  SET previntnum = 0;
  WHILE counter > 0 DO
      SET currentintnum = CAST(convRomanNumeralSubFunction(SUBSTRING(numeral,counter, 1)) as integer);
      IF currentintnum < previntnum THEN
        SET intnum = intnum - currentintnum;
      ELSE 
        SET intnum = intnum + currentintnum;
      END IF;
      SET previntnum = currentintnum;
      SET counter = counter - 1;
  END WHILE;
  RETURN intnum;
END;

$$

就是这样。现在您可以转换各种罗马数字并对其进行排序。 使用它来测试转换:

SELECT convRomanNumeral("XIX");

这是我最后使用的示例排序代码:

SET @iteration = -1;

UPDATE `st0gk_docman_documents` 
    SET created_on = DATE('2016-06-07') + INTERVAL(@iteration := @iteration + 1) SECOND
    WHERE `docman_category_id` = 67 ORDER BY convRomanNumeralBreak(SUBSTRING_INDEX(SUBSTRING_INDEX(title,'/',1),' ',-1)) ASC, SUBSTRING_INDEX(title,'/',-2)+0 ASC;

还有一件事 - 如果您尝试在 mySQL 上执行此操作,那么您必须修复此行:

SET currentintnum = CAST(convRomanNumeralSubFunction(SUBSTRING(numeral,counter, 1)) as integer);

进入这个:

SET currentintnum = CAST(convRomanNumeralSubFunction(SUBSTRING(numeral,counter, 1)) as SIGNED);

此代码可以改进,但正如@Rick James 所说,这应该以不同的方式完成 - 不是作为数据库更新,而是在不同的 table 结构和排序机制中。