5

我有一个用于比较版本的简单 MySQL 函数:

CREATE FUNCTION `compareVersions` (
  versionA VARCHAR(50),
  versionB VARCHAR(50)) RETURNS INT DETERMINISTIC NO SQL
BEGIN
  DECLARE a1 INT;
  DECLARE b1 INT;
   DECLARE c1 INT;
    DECLARE d1 INT;
  DECLARE a2 INT;
  DECLARE b2 INT;
   DECLARE c2 INT;
    DECLARE d2 INT;  SET a1 = SUBSTRING_INDEX( `versionA` , '.', 1 );
  SET b1 = SUBSTRING_INDEX(SUBSTRING_INDEX( `versionA` , '.', 2 ),'.',-1);
  SET c1 = SUBSTRING_INDEX(SUBSTRING_INDEX( `versionA` , '.', -2 ),'.',1);
  SET d1 = SUBSTRING_INDEX( `versionA` , '.', -1 );
  SET a2 = SUBSTRING_INDEX( `versionB` , '.', 1 );
  SET b2 = SUBSTRING_INDEX(SUBSTRING_INDEX( `versionB` , '.', 2 ),'.',-1);
  SET c2 = SUBSTRING_INDEX(SUBSTRING_INDEX( `versionB` , '.', -2 ),'.',1);
  SET d2 = SUBSTRING_INDEX( `versionB` , '.', -1 ); 
  IF (a1 > a2) THEN 
    RETURN -1;
  ELSEIF ((a1 = a2) AND (b1 > b2)) THEN
    RETURN -1;
  ELSEIF ((a1 = a2) AND (b1 = b2) AND (c1 > c2)) THEN
    RETURN -1;
  ELSEIF ((a1 = a2) AND (b1 = b2) AND (c1 = c2) AND (d1 > d2)) THEN
    RETURN -1;
  ELSEIF ((a1 = a2) AND (b1 = b2) AND (c1 = c2) AND (d1 = d2)) THEN  
    RETURN 0;
  ELSE
    RETURN 1;
  END IF;
END $$

它的创建失败了

您没有 SUPER 权限并且启用了二进制日志记录(您 可能希望使用不太安全的 log_bin_trust_function_creators 变量)

这与这个问题几乎相同,但我的函数不读取任何 SQL 数据,它很简单,具有确定性,我认为没有理由需要任何额外的权限。从文档中我不清楚创建所有函数是否需要 SUPER 权限(这很荒谬,使许多用户无法使用存储的函数,每个无权访问其数据库配置的人)。我什至不知道该函数是否有效,这是首先想到的,但语法应该是正确的(分隔符在 PHPMyAdmin 中设置)。可以从数据库中获取所有数据并在 PHP 应用程序中进行比较,但我认为这样做最容易。可能吗?有没有人有更好的解决方案来比较版本?

4

2 回答 2

3

您可以为此调整全局变量:

/* allows to create functions as not root */
SET GLOBAL log_bin_trust_function_creators = 1;

我在 setup-sql 文件中使用它来初始化数据库以恢复转储。

于 2014-06-25T15:19:39.283 回答
2

我通过在 PHP 中进行长而丑陋的数据库查询来规避这个问题。也许使用存储过程而不是函数会更好。搜索后,我在此处的文档中找到了以下声明:

MySQL 5.5 中使用存储函数的现状可以总结如下。[...] 要创建或更改存储函数,除了通常需要的 CREATE ROUTINE 或 ALTER ROUTINE 权限外,您还必须拥有 SUPER 权限。

所以确实,如果二进制日志是打开的,你真的需要超级权限来创建存储函数。这严重限制了存储函数在更大的服务器上的使用,并且在我看来降低了整个 DBMS 的价值。看起来像经典的“它不是错误,它是一个功能”。如果在将二进制日志记录更改为 on 后重新启动数据库服务器,我害怕考虑存储函数会发生什么。

于 2014-07-07T15:13:08.747 回答