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;
所以我想实现的是按标题对文档进行排序。示例标题是:
- 文件编号I/36/2006
- 文档编号 II/36/2006
- 文件编号I/32/2006
- 文件编号II/19/2006
按第一个罗马数字然后按第二个阿拉伯数字对它们进行排序后,我想更新日期。以下仅按第二个阿拉伯数字更新的代码可以正常工作:
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 结构和排序机制中。
任何人都可以帮助我使用我的排序功能 - 说真的,我不知道如何让它按预期工作。 :( 数据库在 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;
所以我想实现的是按标题对文档进行排序。示例标题是:
- 文件编号I/36/2006
- 文档编号 II/36/2006
- 文件编号I/32/2006
- 文件编号II/19/2006
按第一个罗马数字然后按第二个阿拉伯数字对它们进行排序后,我想更新日期。以下仅按第二个阿拉伯数字更新的代码可以正常工作:
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 结构和排序机制中。