zoukankan      html  css  js  c++  java
  • MySQL 错误1418 的原因分析及解决方法

    具体错误:
     使用mysql创建、调用存储过程,函数以及触发器的时候会有错误符号为1418错误。

    [Err] 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)

    查阅相关资料,意思是说binlog启用时,创建的函数没有声明类型,因为binlog在主从复制需要知道这个函数创建语句是什么类型,否则同步数据会有不一致现象。

    mysql开启了bin-log, 我们就必须指定我们的函数是否是哪种类型: 
    1 DETERMINISTIC 不确定的 
    2 NO SQL 没有SQl语句,当然也不会修改数据 
    3 READS SQL DATA 只是读取数据,当然也不会修改数据 
    4 MODIFIES SQL DATA 要修改数据 
    5 CONTAINS SQL 包含了SQL语句


    为了解决这个问题,MySQL强制要求:
    在主服务器上,除非子程序被声明为确定性的或者不更改数据,否则创建或者替换子程序将被拒绝。这意味着当创建一个子程序的时候,必须要么声明它是确定性的,要么它不改变数据。

    声明方式有两种:
    第一种:声明是否是确定性的
    DETERMINISTIC和NOT DETERMINISTIC指出一个子程序是否对给定的输入总是产生同样的结果。
    如果没有给定任一特征,默认是NOT DETERMINISTIC,所以必须明确指定DETERMINISTIC来声明一个子程序是确定性的。 
    这里要说明的是:使用NOW() 函数(或它的同义)或者RAND() 函数不会使一个子程序变成非确定性的。对NOW()而言,二进制日志包括时间戳并会被正确的执行。RAND()只要在一个子程序内被调用一次也可以被正确的复制。所以,可以认为时间戳和随机数种子是子程序的确定性输入,它们在主服务器和从服务器上是一样的。
    第二种:声明是否会改变数据  
    CONTAINS SQL, NO SQL, READS SQL DATA, MODIFIES SQL用来指出子程序是读还是写数据的。
    无论NO SQL还是READS SQL DATA都指出,子程序没有改变数据,但是必须明确地指定其中一个,因为如果任何指定,默认的指定是CONTAINS SQL。
    默认情况下,如果允许CREATE PROCEDURE 或CREATE FUNCTION 语句被接受,就必须明确地指定DETERMINISTIC 或 NO SQL与READS SQL DATA 中的一个,否则就会产生1418错误。

    解决办法也有两种:
    第一种是在创建子程序(存储过程、函数、触发器)时,声明为DETERMINISTIC或NO SQL与READS SQL DATA中的一个,
    例如:

    DROP FUNCTION IF EXISTS `t_auto_increment`;
    DELIMITER ;;
    CREATE FUNCTION `t_auto_increment`(`seq_name` tinyint) RETURNS varchar(50) CHARSET utf8
    DETERMINISTIC
    BEGIN
    declare v_prefix VARCHAR(20);
    update t_auto_increment a set a.currentvalue=LAST_INSERT_ID(a.currentvalue+a.incrementBy) where a.autoKey=seq_name;
    select prefix into v_prefix from t_auto_increment where autoKey=seq_name;
    RETURN CONCAT(CASE WHEN v_prefix  is null THEN '' ELSE  v_prefix END,LAST_INSERT_ID());
    END
    ;;
    DELIMITER ;


    第二种是信任子程序的创建者,禁止创建、修改子程序时对SUPER权限的要求,设置log_bin_trust_routine_creators全局系统变量为1。设置方法有三种:

    1.在客户端上执行SET GLOBAL log_bin_trust_function_creators = 1;
    2.MySQL启动时,加上--log-bin-trust-function-creators选贤,参数设置为1
    3.在MySQL配置文件my.ini或my.cnf中的[mysqld]段上加log-bin-trust-function-creators=1

  • 相关阅读:
    poj3278 Catch That Cow
    poj2251 Dungeon Master
    poj1321 棋盘问题
    poj3083 Children of the Candy Cor
    jvm基础知识—垃圾回收机制
    jvm基础知识1
    java面试基础必备
    java soket通信总结 bio nio aio的区别和总结
    java scoket aIO 通信
    java scoket Blocking 阻塞IO socket通信四
  • 原文地址:https://www.cnblogs.com/shenyixin/p/11305214.html
Copyright © 2011-2022 走看看