在 MySQL 和 MariaDB 中创建交叉兼容的垃圾字符串函数时出错

Posted

技术标签:

【中文标题】在 MySQL 和 MariaDB 中创建交叉兼容的垃圾字符串函数时出错【英文标题】:Error creating a cross compatible garbage string function in MySQL and MariaDB 【发布时间】:2014-02-01 22:02:17 【问题描述】:

如您所知,MariaDB 的小版本 (5.5-) 据说与 mysql 兼容(我发现了缺陷,但他们说它是 90%)。我在我们的环境中使用两者,AWS RDS 上的 MySQL 和我们本地开发服务器和开发盒上的 Maria。我目前正在尝试组合一个函数,该函数将使用随机数据自动填充一行

表结构会很简单,像这样

DROP DATABASE IF EXISTS `foodb`;
CREATE DATABASE `foodb`;
USE `foodb`;

DROP TABLE IF EXISTS `footable`;
CREATE TABLE `footable` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `garbage`    varchar(128) DEFAULT garbageString(),
   PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

函数garbageString() 是这样的

DROP FUNCTION IF EXISTS garbageString;
CREATE FUNCTION garbageString($length int)
  RETURNS varchar(128)
  BEGIN

    SET @chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    SET @charLen = length(@chars);

    SET @randomString = '';

    WHILE length(@randomString) < $length DO
      SET @randomString = concat(@randomString, substring(@chars,CEILING(RAND() * @charLen),1));
    END WHILE;

    RETURN @randomString ;
  END;

虽然 MySQL 和 Maria 都试图让这个函数运行,但我很头疼,这是来自 MY 的错误转储

MySQL [foodatabase]> CREATE FUNCTION garbageString($length int)
    ->   RETURNS varchar(128)
    ->   BEGIN
    -> 
    ->     SET @chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
ERROR 1064 (42000): 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 '' at line 5
MySQL [foodatabase]>     SET @charLen = length(@chars);
Query OK, 0 rows affected (0.03 sec)

MySQL [foodatabase]> 
MySQL [foodatabase]>     SET @randomString = '';
Query OK, 0 rows affected (0.03 sec)

MySQL [foodatabase]> 
MySQL [foodatabase]>     WHILE length(@randomString) < $length DO
    ->       SET @randomString = concat(@randomString, substring(@chars,CEILING(RAND() * @charLen),1));
ERROR 1064 (42000): 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 length(@randomString) < $length DO
      SET @randomString = concat(@rando' at line 1
MySQL [foodatabase]>     END WHILE;
ERROR 1064 (42000): 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 'END WHILE' at line 1
MySQL [foodatabase]> 
MySQL [foodatabase]>     RETURN @randomString ;
ERROR 1064 (42000): 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 'RETURN @randomString' at line 1
MySQL [foodatabase]>   END;

这是玛丽亚的一个

MariaDB [foodatabase]> CREATE FUNCTION garbageString($length int)
    ->   RETURNS varchar(128)
    ->   BEGIN
    -> 
    ->     SET @chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
ERROR 1064 (42000): 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 '' at line 5
MariaDB [foodatabase]>     SET @charLen = length(@chars);
Query OK, 0 rows affected (0.00 sec)

MariaDB [foodatabase]> 
MariaDB [foodatabase]>     SET @randomString = '';
Query OK, 0 rows affected (0.00 sec)

MariaDB [foodatabase]> 
MariaDB [foodatabase]>     WHILE length(@randomString) < $length DO
    ->       SET @randomString = concat(@randomString, substring(@chars,CEILING(RAND() * @charLen),1));
ERROR 1064 (42000): 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 'WHILE length(@randomString) < $length DO
      SET @randomString = concat(@rando' at line 1
MariaDB [foodatabase]>     END WHILE;
ERROR 1064 (42000): 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 'END WHILE' at line 1
MariaDB [foodatabase]> 
MariaDB [foodatabase]>     RETURN @randomString ;
ERROR 1064 (42000): 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 'RETURN @randomString' at line 1
MariaDB [foodatabase]>   END;

有什么方法可以让这个函数工作,并让它在两种数据库类型上工作?

看起来他们都在同一个地方窒息,我只是不想有任何意外

【问题讨论】:

【参考方案1】:

使用命令行客户端定义函数或过程时,您需要更改DELIMITER。命令行客户端检查当前查询分隔符的输入,此时将多个查询分开,并将查询一一发送到服务器。

通常的分隔符是;,但它也用作 ANSI 过程语言中的命令分隔符,因此您的过程代码会被分解成小的和平,这些和平本身不是有效的 SQL 语句。因此,您需要将客户端分隔符更改为其他内容,例如//:

DELIMITER //

在此之后,您可以很好地输入您的过程文本,而不会出现您当前遇到的错误,并在其末尾添加 // 以告诉客户端将完整的过程文本作为单个语句发送到服务器.

然后,如果您愿意,可以将分隔符改回;

DELIMITER ;

【讨论】:

以上是关于在 MySQL 和 MariaDB 中创建交叉兼容的垃圾字符串函数时出错的主要内容,如果未能解决你的问题,请参考以下文章

在 MySQL/MariaDB 中创建存储过程时出错

如何在 mariadb 或 mysql 中创建临时表?

如何在 MySQL/MariaDB 中创建与 root 具有相同权限的用户? [关闭]

在交叉引用表中创建具有两个外键的 MySQL 表

当我在 MariaDB/MySQL 中创建附有注释的索引时,该注释存储在哪里?

如何在 mariaDB 中创建检查约束以检查 char 类型的多个值?