【问题标题】:Error in create function syntax developed with MySql not working in MariaDB on PhpMyAdmin SQL console使用 MySql 开发的创建函数语法错误在 PhpMyAdmin SQL 控制台上的 MariaDB 中不起作用
【发布时间】:2022-10-16 12:13:22
【问题描述】:

我有以下创建函数用于 SQL 的块

/**
 * tos_get_duration.sql
 *
 * Given time unit in seconds, it converts to more readable format
 *
 * Eg. SELECT TOS_GET_DURATION(72) => 00d 0:1:12
 */

DROP FUNCTION IF EXISTS TOS_GET_DURATION;
DELIMITER $$
CREATE FUNCTION TOS_GET_DURATION(seconds INT) 
  RETURNS VARCHAR(16) 
BEGIN
  RETURN CONCAT(LPAD(FLOOR(HOUR(SEC_TO_TIME(seconds)) / 24), 2, 0), ' days ',TIME_FORMAT(SEC_TO_TIME(seconds % (24 * 3600)), '%H:%i:%s'));
END; 
$$
DELIMITER;

它取自timeonsite analytics reporting 查询页面。

它曾经在 MySql 中运行良好,但我最近切换到 MariaDB 并尝试执行此功能;这个函数基本上将秒转换为更易读的字符串格式。我收到以下错误:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DELIMITER' at line 1

Server version: 10.5.16-MariaDB - MariaDB Server

请帮助我找到问题并建议我可以在两者中使用的常见“创建函数”格式MySql 和 MariaDB 数据库。

【问题讨论】:

  • DELIMITER 不是 SQL 语句,而是客户端命令。阅读有关如何正确创建存储对象的 PhpMyAdmin 文档。
  • PS。在您的特定情况下,您可以简单地删除 BEGIN-END 和两个 DELIMITER 行。
  • '建议我可以在 MySql 和 MariaDB 数据库中使用的常见“创建函数”格式。' - 不能这样做 mysql 和 mariadb 正在发散,并且已经发散到不能将 mariadb 视为 mysql 替代品的地步。 (在我看来)
  • DELIMITERDETERMINISTIC 关键字之后需要一个空格。见DelimitresCREATE FUNCTION - MySQL 8 fiddle
  • 这回答了你的问题了吗? phpMyadmin DELIMITER Error True or False?

标签: mysql sql mariadb


【解决方案1】:

感谢您宝贵的cmets。我对每一个 cmets 都投了赞成票,因为它们非常有价值。根据您的建议,我为两者创建了一个共同的小提琴并在此处分享。关键是,我们可以删除开始/结束声明并删除分隔符关键字也是如此。

通用代码在 MySQL 和 MariaDB 中都有效,除了 MySQL 最新版本期望确定性关键字工作。

玛丽亚数据库https://dbfiddle.uk/PK8F8ng4

DROP FUNCTION IF EXISTS TOS_GET_DURATION;
CREATE FUNCTION TOS_GET_DURATION(seconds INT) 
  RETURNS VARCHAR(16)
  RETURN CONCAT(LPAD(FLOOR(HOUR(SEC_TO_TIME(seconds)) / 24), 2, 0), ' days ',TIME_FORMAT(SEC_TO_TIME(seconds % (24 * 3600)), '%H:%i:%s'));

SELECT TOS_GET_DURATION(860000);

MySQLhttps://www.db-fiddle.com/f/qsDtYVw7GrkJW5suNsrfd1/9

DROP FUNCTION IF EXISTS TOS_GET_DURATION;
CREATE FUNCTION TOS_GET_DURATION(seconds INT) 
  RETURNS VARCHAR(16) DETERMINISTIC
  RETURN CONCAT(LPAD(FLOOR(HOUR(SEC_TO_TIME(seconds)) / 24), 2, 0), ' days ',TIME_FORMAT(SEC_TO_TIME(seconds % (24 * 3600)), '%H:%i:%s'));

SELECT TOS_GET_DURATION(860000);

输出:

09 days 22:53:20

我也同意 Salmon 的观点,

不能这样做 mysql 和 mariadb 正在发散并且已经发散到 不能将 mariadb 视为替代品的点 mysql。

但关键是,我们有许多应用程序是作为 LAMP 堆栈的一部分构建的。所以,我们暂时需要这样的通用代码格式,方便切换。我们将保持开放,以听取其他人的更多建议。当我在尝试运行查询复杂子查询以分析 Web 应用程序中的用户参与度时,首次发现此问题。

查找应用程序中用户参与度最高的 10 个会话:

第 2 行使用用户定义的函数TOS_GET_DURATION在 MariaDB 中

SELECT 
  TOS_GET_DURATION(max_timeonsite) as 'Session Duration', 
  tos_session_key 
FROM 
  (
    SELECT 
      MAX(timeonsite) AS max_timeonsite, 
      tos_session_key 
    FROM 
      tos 
    GROUP BY 
      tos_session_key 
    ORDER BY 
      max_timeonsite DESC 
    LIMIT 
      10
  ) timeonsite_large_sessions;

查询输出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 2011-04-19
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多