mysql添加函数时出错

标签 mysql replication cumulative-sum

尝试使用 MySQL 函数时返回以下错误..

#1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its
declaration and binary logging is enabled (you *might* want to use the less safe 
log_bin_trust_function_creators variable) 

几天前我开始使用复制..?不知道这个会不会有影响?!但我知道一件事 - 它奏效了 :)

如果我尝试重写(再次添加函数),会发生同样的错误。

函数

DELIMITER $$

DROP FUNCTION IF EXISTS `stock_in_stock_ids` $$
CREATE DEFINER=`dynaccount`@`localhost` FUNCTION `stock_in_stock_ids`(_running_total_limit INT, _product_id INT, _group_id INT) RETURNS TEXT
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE _running_count INT default 0;
    DECLARE _id INT;
    DECLARE _count INT;
    DECLARE _ids TEXT DEFAULT NULL;

    DECLARE _cur CURSOR FOR SELECT id, count FROM stock WHERE group_id=_group_id && type=2 && product_id=_product_id ORDER BY time DESC, id DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN _cur;

    read_loop: LOOP
        FETCH _cur INTO _id, _count;

        IF done THEN
            SET _ids = '0';
            LEAVE read_loop;
        END IF;

        SET _running_count = _running_count + _count;
        SET _ids = CONCAT_WS(',', _ids, _id);

        IF _running_count >= _running_total_limit THEN
            LEAVE read_loop;
        END IF;
    END LOOP read_loop;

    CLOSE _cur;

    RETURN _ids;
END $$

DELIMITER ;

最佳答案

这里有一篇帖子可以让我在过去了解这个错误: http://forum.9kgames.com/default.aspx?g=posts&m=17

在我的例子中,我只需要在创建函数中指定 DETERMINISTIC:

CREATE DEFINER=`dynaccount`@`localhost` FUNCTION `stock_in_stock_ids`(_running_total_limit INT, _product_id INT, _group_id INT) 
RETURNS TEXT
DETERMINISTIC
READS SQL DATA

希望对你有帮助

更新:链接不再有效,所以这里是 archive.org 的副本:https://web.archive.org/web/20120310020353/http://forum.9kgames.com/default.aspx?g=posts&m=17

此警告在

一个)。你想创建一个存储函数并且 b).由于默认的 MySQL 服务器支持复制,即 BINARY LOGGING 已打开。 要解决此问题,这里有一些提示:

1).对于存储函数本身。创建存储函数时,必须声明它是确定性的或不修改数据。否则,数据恢复或复制可能不安全。 默认情况下,要接受 CREATE FUNCTION 语句,DETERMINISTICNO SQLREADS SQL DATA< 中的至少一项 必须明确指定。否则会出现错误: 代码:

ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL,
or READS SQL DATA in its declaration and binary logging is enabled
(you *might* want to use the less safe log_bin_trust_function_creators
variable).

这个函数是确定性的(并且不修改数据),所以它是安全的: 代码:

CREATE FUNCTION f1(i INT)
RETURNS INT
DETERMINISTIC
READS SQL DATA
BEGIN
  RETURN i;
END;

此函数使用不确定的 UUID(),因此该函数也不确定且不安全: 代码:

CREATE FUNCTION f2()
RETURNS CHAR(36) CHARACTER SET utf8
BEGIN
  RETURN UUID();
END;

此函数修改数据,因此可能不安全: 代码:

CREATE FUNCTION f3(p_id INT)
RETURNS INT
BEGIN
  UPDATE t SET modtime = NOW() WHERE id = p_id;
  RETURN ROW_COUNT();
END;

MySQL 不检查声明为 DETERMINISTIC 的函数是否没有产生非确定性结果的语句。 虽然可以在不指定 DETERMINISTIC 的情况下创建确定性存储函数,但从 MySQL 5.1.15 开始,您不能使用基于语句的二进制日志记录来执行此函数。要执行这样的功能,您必须使用基于行的或混合的二进制日志记录。或者,如果您在函数定义中明确指定 DETERMINISTIC,则可以使用任何类型的日志记录,包括基于语句的日志记录。

2)虽然你已经完成了第1步,但在大多数情况下,你可能仍然需要SUPER权限来设置全局变量log_bin_trust_function_creators为true,然后运行创建存储函数。 要放宽函数创建的上述条件(您必须具有 SUPER 权限并且函数必须声明为确定性的或不修改数据),请将全局 log_bin_trust_function_creators 系统变量设置为 1。默认情况下,此变量的值为 0,但您可以这样更改它:

mysql> SET GLOBAL log_bin_trust_function_creators = 1;

您还可以在启动服务器时使用 log_bin_trust_function_creators 选项设置此变量。 如果未启用二进制日志记录,则 log_bin_trust_function_creators 不适用。函数创建不需要 SUPER,除非如前所述,函数定义中的 DEFINER 值需要它。 注意:如果您的应用程序在 Multi-Tenancy 托管服务器上运行并且托管公司不希望这样做,您可能需要修改存储过程而不是使用存储函数。

关于mysql添加函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11316008/

相关文章:

java - 如何使用 Spring MySQL 和 RowCallbackHandler 管理大型数据集

python - 如何将其转换为 unicode 以便正确显示?

mysql - 搜索并替换 from 标签后 ""之间的字符串

mysql - 如果我将数据更新/插入到从属数据库中的复制中被忽略的表中,会发生什么情况?

python - 从累加和中获取原始值

mysql - 取两个特定字符之间的数字

mysql - 自己做MySQL行复制的问题

java - Tomcat 集群 6 和 ContextListener

mysql - 尝试从我即时求和的列中获取累积总和

python - 条件 numpy 累计和