mysql命令行创建函数

mysql命令行模式下创建函数

1、修改命令分隔符为 “$$”,防止执行中函数中的 “;” 符截断函数

delimiter $$

2、执行创建函数

CREATE DEFINER=`root`@`%` FUNCTION `huai_GETPARLST`(rootId VARCHAR(32)) RETURNS varchar(1000) CHARSET utf8
BEGIN
 DECLARE sTemp VARCHAR(1000);
 DECLARE sTempPar VARCHAR(1000);
  DECLARE namesss VARCHAR(1000); 
 DECLARE namek VARCHAR(1000); 
 SET sTemp = ''; 
 SET sTempPar = rootId; 
 SET namesss = '';
 SET namek = '';
 WHILE sTempPar is not null and sTempPar <> '' DO 
  IF sTemp != '' THEN
   SET sTemp = concat(sTempPar,',',sTemp);
   SELECT `name` INTO namek FROM flow_gathering_area where id = sTempPar;
   IF namek != '' THEN
   SET namesss = concat(namek,',',namesss);
   ELSE
   SET namesss = namesss;
   END IF;
  ELSE
   SET sTemp = sTempPar;
   SELECT `name` INTO namesss FROM flow_gathering_area where id = sTempPar;
  END IF;
  SELECT group_concat(parent_id) INTO sTempPar FROM flow_gathering_area where parent_id<>id and FIND_IN_SET(id,sTempPar)>0; 
 END WHILE; 
RETURN namesss; 
END$$

执行成功
在这里插入图片描述
3、恢复命令分隔符为 ";"

delimiter ;

中间遇到的问题

1、ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL

意思就是mysql现在是不允许创建函数。此时如何解决这个问题呢?分二种情况。
①、单个数据库,数据库没有开启主从复制。

1、更改全局配置(重启服务失效)
      SET GLOBAL log_bin_trust_function_creators = 1;  
      有主从复制的时候 , 从机必须要设置  不然会导致主从同步失败
2、更改配置文件my.cnf  
      log-bin-trust-function-creators=1   重启服务生效

MySQL参数log_bin_trust_function_creators 简单介绍

当二进制日志启用后,这个变量就会启用。它控制是否可以信任存储函数创建者,
不会创建写入二进制日志引起不安全事件的存储函数。如果设置为0(默认值),
用户不得创建或修改存储函数,除非它们具有除CREATE ROUTINE或ALTER ROUTINE特权之外的SUPER权限。
 设置为0还强制使用DETERMINISTIC特性或READS SQL DATA或NO SQL特性声明函数的限制。 
 如果变量设置为1,MySQL不会对创建存储函数实施这些限制。 此变量也适用于触发器的创建。

查看mysql参数log_bin_trust_function_creators状态

mysql> show variables like '%func%';  
+---------------------------------+-------+  
| Variable_name                   | Value |  
+---------------------------------+-------+  
| log_bin_trust_function_creators | OFF   |  
+---------------------------------+-------+  
1 row in set (0.00 sec)  

OFF代表0,此时执行创建函数就会报此异常。

②、数据库开启主从复制(主从复制会开启二进制日志,此处也可以使用第一种方式解决)[推荐]。
明确指明函数的类型,如果我们开启了二进制日志, 那么我们就必须为我们的function指定一个参数。其中下面几种参数类型里面,只有 DETERMINISTIC, NO SQL 和 READS SQL DATA 被支持。这样一来相当于明确的告知MySQL服务器这个函数不会修改数据。

 1. DETERMINISTIC 确定的
 2. NO SQL 没有SQl语句,当然也不会修改数据
 3. READS SQL DATA 只是读取数据,当然也不会修改数据
 4. MODIFIES SQL DATA 要修改数据
 5. CONTAINS SQL 包含了SQL语句

修改完之后的函数

CREATE DEFINER=`root`@`%` FUNCTION `huai_GETPARLST`(rootId VARCHAR(32)) RETURNS varchar(1000) CHARSET utf8
READS SQL DATA 
BEGIN
 DECLARE sTemp VARCHAR(1000);
 DECLARE sTempPar VARCHAR(1000);
  DECLARE namesss VARCHAR(1000); 
 DECLARE namek VARCHAR(1000); 
 SET sTemp = ''; 
 SET sTempPar = rootId; 
 SET namesss = '';
 SET namek = '';
 WHILE sTempPar is not null and sTempPar <> '' DO 
  IF sTemp != '' THEN
   SET sTemp = concat(sTempPar,',',sTemp);
   SELECT `name` INTO namek FROM flow_gathering_area where id = sTempPar;
   IF namek != '' THEN
   SET namesss = concat(namek,',',namesss);
   ELSE
   SET namesss = namesss;
   END IF;
  ELSE
   SET sTemp = sTempPar;
   SELECT `name` INTO namesss FROM flow_gathering_area where id = sTempPar;
  END IF;
  SELECT group_concat(parent_id) INTO sTempPar FROM flow_gathering_area where parent_id<>id and FIND_IN_SET(id,sTempPar)>0; 
 END WHILE; 
RETURN namesss; 
END$$

那么为什么MySQL有这样的限制呢? 因为我们的数据库是主从复制的,所以会开启二进制日志。二进制日志的一个重要功能是用于主从复制,而存储函数有可能导致主从的数据不一致。所以当开启二进制日志后,参数log_bin_trust_function_creators就会生效,限制存储函数的创建、修改、调用。
2、The user specified as a definer (‘root’@’%’) does not exist
权限问题,由于此函数不需要权限限制,都可以使用,所以去掉权限限制。
修改完之后的函数(去掉 DEFINER=root@%

CREATE FUNCTION `huai_GETPARLST`(rootId VARCHAR(32)) RETURNS varchar(1000) CHARSET utf8
READS SQL DATA
BEGIN
 DECLARE sTemp VARCHAR(1000);
 DECLARE sTempPar VARCHAR(1000);
  DECLARE namesss VARCHAR(1000); 
 DECLARE namek VARCHAR(1000); 
 SET sTemp = ''; 
 SET sTempPar = rootId; 
 SET namesss = '';
 SET namek = '';
 WHILE sTempPar is not null and sTempPar <> '' DO 
  IF sTemp != '' THEN
   SET sTemp = concat(sTempPar,',',sTemp);
   SELECT `name` INTO namek FROM flow_gathering_area where id = sTempPar;
   IF namek != '' THEN
   SET namesss = concat(namek,',',namesss);
   ELSE
   SET namesss = namesss;
   END IF;
  ELSE
   SET sTemp = sTempPar;
   SELECT `name` INTO namesss FROM flow_gathering_area where id = sTempPar;
  END IF;
  SELECT group_concat(parent_id) INTO sTempPar FROM flow_gathering_area where parent_id<>id and FIND_IN_SET(id,sTempPar)>0; 
 END WHILE; 
RETURN namesss; 
END$$

参考:https://www.cnblogs.com/kerrycode/p/7641835.html

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 MySQL 命令行创建自定义函数,可以按照以下步骤进行操作: 1. 打开 MySQL 命令行客户端,使用适当的凭据登录到 MySQL 服务器。 2. 使用以下语法创建一个新的自定义函数: ```sql CREATE FUNCTION function_name ([parameters]) RETURNS return_type [DETERMINISTIC] BEGIN -- 函数体 END; ``` - `function_name` 是你为函数选择的名称。 - `parameters` 是函数接受的参数列表。 - `return_type` 是函数返回的数据类型。 - `DETERMINISTIC` 关键字可选,用于指示函数是否是确定性的(即,对于给定的输入,是否总是返回相同的结果)。 3. 在函数体中编写实际的函数逻辑。你可以使用 SQL 语句、控制流程语句、变量等。 4. 使用 `DELIMITER` 命令更改语句分隔符为非默认值(例如 `$$`),这样可以在函数体中使用分号 (`;`)。 ```sql DELIMITER $$ CREATE FUNCTION function_name ([parameters]) RETURNS return_type [DETERMINISTIC] BEGIN -- 函数体 END $$ DELIMITER ; ``` 5. 提交该语句以创建自定义函数。 以下是一个示例,创建一个简单的自定义函数来计算两个数的和: ```sql DELIMITER $$ CREATE FUNCTION sum_of_two_numbers(a INT, b INT) RETURNS INT DETERMINISTIC BEGIN DECLARE result INT; SET result = a + b; RETURN result; END $$ DELIMITER ; ``` 现在你可以在 MySQL 命令行中调用这个自定义函数: ```sql SELECT sum_of_two_numbers(3, 5); ``` 该查询将返回结果 8。 请注意,这只是一个简单的示例,你可以根据需求编写更复杂的自定义函数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值