MySQL This function has none of DETERMINISTIC, NO SQL...Cause analysis and solution of error 1418

MySQL开启bin-log后,调用存储过程或者函数以及触发器时,会出现错误号为1418的错误:

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)

我本机的错误:

{"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)"}
    [MySql.Data.MySqlClient.MySqlException]: {"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)"}
    Data: {System.Collections.ListDictionaryInternal}
    HelpLink: null
    InnerException: null
    Message: "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)"
    Source: "MySql.Data"
    StackTrace: "   在 MySql.Data.MySqlClient.MySqlStream.OpenPacket()\r\n   在 MySql.Data.MySqlClient.NativeDriver.ReadResult(UInt64& affectedRows, Int64& lastInsertId)\r\n   在 MySql.Data.MySqlClient.MySqlDataReader.GetResultSet()\r\n   在 MySql.Data.MySqlClient.MySqlDataReader.NextResult()\r\n   在 MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)\r\n   在 MySql.Data.MySqlClient.MySqlCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   在 System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)\r\n   在 System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)\r\n   在 System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord,Int32 maxRecords, IDbCommand command, CommandBehavior behavior)\r\n   在 System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)\r\n   在 Nie.Data.MYYSQL.ExecuteStored(String p
rocedureName, String[,] ps)\r\n in Nie.Data.MYSQLSTATIC.cmdStoredDataTable(String pn, String[,] ps)"
    TargetSite: {Void OpenPacket()}


Cause analysis:

Because CREATE PROCEDURE, CREATE FUNCTION, ALTER Statements such as PROCEDURE, ALTER FUNCTION, CALL, DROP PROCEDURE, DROP FUNCTION will be written to the binary log and then executed on the slave server. However, an indeterminate subroutine (stored procedure, function, trigger) that performs an update is not repeatable Yes, executing on the slave server (relative to the master server) may cause the recovered data to be different from the original data, and the slave server is different from the master server.

To solve this problem, MySQL enforces:
on the master server, Creating or replacing a subroutine will be rejected unless the subroutine is declared deterministic or does not change data.
This means that when creating a subroutine, it must either be declared deterministic or it does not change data.

There are two ways to declare,
the first: whether the declaration is deterministic
DETERMINISTIC and NOT DETERMINISTIC indicate whether a subroutine always produces the same result for a given input.
If neither feature is given, the default is NOT DETERMINISTIC, So DETERMINISTIC must be specified explicitly to declare a subroutine to be deterministic.
The caveat here is that using the NOW() function (or its synonym) or the RAND() function does not make a subroutine non-deterministic. For NOW(), the binary log includes timestamps and will be executed correctly. RAND() can be copied correctly as long as it is called once within a subroutine. Therefore, www.linuxidc.com can consider the timestamp and random number seed as deterministic input to the subroutine, and they are the same on the master and slave servers.

The second: whether the statement will change the data 
CONTAINS SQL, NO SQL, READS SQL DATA, MODIFIES SQL is used to indicate whether the subroutine reads or writes data.
Either NO SQL or READS SQL DATA point out that the subroutine did not change the data, but one must be specified explicitly, because if any are specified, the default is CONTAINS SQL.

By default, if a CREATE PROCEDURE or CREATE FUNCTION statement is allowed to be accepted, one of DETERMINISTIC or NO SQL and READS SQL DATA must be specified explicitly, otherwise a 1418 error will be generated.

Solution:

There are two solutions.
The first is to declare one of DETERMINISTIC or NO SQL and READS SQL DATA when creating a subprogram (stored procedure, function, trigger), for
example:
CREATE DEFINER = CURRENT_USER PROCEDURE ` NewProc`()
    DETERMINISTIC
BEGIN
#Routine body goes here...
END;;

The second is to trust the creator of the subroutine, prohibit the requirement for SUPER permission when creating and modifying the subroutine, and set the log_bin_trust_routine_creators global system variable to 1. There are three setting methods:
1. Execute SET GLOBAL log_bin_trust_function_creators = 1 on the client;
2. When MySQL starts, add --log-bin-trust-function-creators and set the parameter to 1
3. In the MySQL configuration file Add log-bin-trust-function-creators=1 to the [mysqld] section in my.ini or my.cnf for other solutions on the network. The same is true. Error message when creating a

function: 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) Reason: This is when we have enabled bin-log, we must specify our Whether the function is 1 DETERMINISTIC Uncertain 2 NO SQL No SQl statement, of course will not modify the data 3 READS SQL DATA just read the data, of course will not modify the data















4 MODIFIES SQL DATA To modify data
5 CONTAINS SQL contains SQL statements

Among the functions, only DETERMINISTIC, NO SQL and READS SQL DATA are supported. If we have bin-log enabled, we must specify an argument to our function.


A workaround for this error when creating a function in MySQL:
set global log_bin_trust_function_creators=TRUE;

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325976804&siteId=291194637