MySQL存储函数错误[Err] 1064的调试记录

本文详细解析了在MySQL中创建存储函数时遇到的常见错误,包括语法错误和权限问题,并提供了具体的修正步骤和示例代码,帮助读者理解如何正确地创建和使用存储函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,朋友创建存储函数报错。CREATE DEFINER=`root`@`localhost` FUNCTION `stuff`(
 f_old varchar(1000),f_start int,f_length int,f_replace varchar(1000)
) RETURNS varchar(2000) CHARSET utf8
BEGIN
  return replace(f_old,substring(f_old,f_start,f_length),f_replace);
END


[SQL] create   FUNCTION  f_Int2IP (ip bigint)  RETURNS   varchar(15) 
BEGIN
DECLARE   re   varchar(15) default '';
SELECT  concat('.',CAST(ip/id  as  char)),ip%id into re,ip
from(
    SELECT  16777216   as id
    UNION   ALL   SELECT   65536
    UNION   ALL   SELECT   256
    UNION   ALL   SELECT   1) a;
set 
RETURN STUFF(re,1,1,'');
END  

报错如下: 
[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'varchar)),ip%id into re,ip
from(
    SELECT  16777216   as id
    UNION   ALL   SEL' at line 4


二、查看创建函数的功能是否开启:
先看下,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)


如果Value处值为OFF,则需将其开启。
mysql> set global log_bin_trust_function_creators=1;
Query OK, 0 rows affected (0.00 sec)


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


三,分析
mysql存储函数,需要特殊的间隔符来区分,还要用DELIMITER来标示,还有select ... into ... 已经赋值了,set就是多余的,所以修改如下:
DELIMITER $$
DROP FUNCTION IF EXISTS test.stuff$$
CREATE FUNCTION test.`stuff`(
 f_old VARCHAR(1000),f_start INT,f_length INT,f_replace VARCHAR(1000)
) RETURNS VARCHAR(2000) 
BEGIN
  RETURN REPLACE(f_old,SUBSTRING(f_old,f_start,f_length),f_replace);
END$$


DELIMITER $$
DROP FUNCTION IF EXISTS test.f_Int2IP$$
CREATE FUNCTION `test`.`f_Int2IP`(ip BIGINT)
    RETURNS VARCHAR(2000)
    BEGIN
DECLARE re VARCHAR(2000) DEFAULT '';
SELECT CONCAT('.',CAST(ip/id  AS  CHAR)) AS restr,ip%id INTO re ,ip
FROM(
   SELECT  16777216   AS id
   UNION   ALL   SELECT   65536
   UNION   ALL   SELECT   256
   UNION   ALL   SELECT   1) a;
RETURN stuff(re,1,1,',');
    END$$
DELIMITER ;


四,执行如下,都OK。
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> DELIMITER $$
mysql> DROP FUNCTION IF EXISTS test.stuff$$
Query OK, 0 rows affected (0.00 sec)


mysql> CREATE FUNCTION test.`stuff`(
    ->  f_old VARCHAR(1000),f_start INT,f_length INT,f_replace VARCHAR(1000)
    -> ) RETURNS VARCHAR(2000) 
    -> BEGIN
    ->   RETURN REPLACE(f_old,SUBSTRING(f_old,f_start,f_length),f_replace);
    -> END$$
Query OK, 0 rows affected (0.01 sec)


mysql> 
mysql> DELIMITER $$
mysql> DROP FUNCTION IF EXISTS test.f_Int2IP$$
Query OK, 0 rows affected (0.00 sec)


mysql> CREATE FUNCTION `test`.`f_Int2IP`(ip BIGINT)
    ->     RETURNS VARCHAR(2000)
    ->     BEGIN
    -> DECLARE re VARCHAR(2000) DEFAULT '';
    -> SELECT CONCAT('.',CAST(ip/id  AS  CHAR)) AS restr,ip%id INTO re ,ip
    -> FROM(
    ->     SELECT  16777216   AS id
    ->     UNION   ALL   SELECT   65536
    ->     UNION   ALL   SELECT   256
    ->     UNION   ALL   SELECT   1) a;
    -> RETURN stuff(re,1,1,',');
    ->     END$$
Query OK, 0 rows affected (0.00 sec)


mysql> DELIMITER ;
mysql> 


后补一下带int的函数
delimiter $$
CREATE FUNCTION first_func(param1 varchar(5),parmam2 varchar(5),param3 varchar(10))
RETURNS TINYINT
BEGIN
   RETURN 1;
END

PS:mysql的存储函数或者存储过程么有直接可以调试的工具,所以需要手工仔细分析查看,应用中尽量少用存储过程或者存储函数。

<think>好的,用户现在想了解在MySQL中执行存储过程的命令和用法。首先,我需要回顾之前提供的关于存储过程的引用内容,确保回答准确。用户之前的问题提到了存储过程的参数类型、创建语法以及执行存储过程的示例,比如引用[2]中的IN、OUT、INOUT参数类型,以及引用[3]中的存储函数示例。 用户当前的提问是执行存储过程的语法和命令,我需要先明确执行存储过程的基本方法。根据已有的知识,执行存储过程通常使用CALL语句,后面跟上过程名和参数。例如,CALL procedure_name(param1, param2);。同时,如果存储过程有输出参数,用户可能需要使用会话变量来获取结果,如引用[2]中的OUT参数处理。 接下来,我需要考虑用户可能的实际应用场景,比如如何传递不同类型的参数,如何处理返回的结果,以及如何调试存储过程。例如,用户可能需要知道如何声明变量、设置会话变量,或者如何查看存储过程的输出。此外,引用[4]中的UPDATE语句可能涉及到在存储过程中执行数据操作,这也是一个需要注意的地方。 还要注意用户可能混淆存储过程和存储函数,根据引用[3],存储函数必须返回一个值,而存储过程可以没有返回值或有多个输出参数。因此,在回答时需要区分两者的执行方式,存储函数使用SELECT调用,而存储过程使用CALL。 另外,用户可能在创建存储过程时遇到分隔符的问题,如引用[1]提到的DELIMITER命令,修改默认的;为其他符号如//,以避免语句在创建过程中被提前执行。这也需要在回答中提到,特别是在创建存储过程的步骤中。 还需要考虑用户可能的错误处理,比如参数类型不匹配、权限问题,或者如何查看已有的存储过程。这些可以通过SHOW PROCEDURE STATUS和SHOW CREATE PROCEDURE命令来实现,帮助用户管理和调试他们的存储过程。 最后,需要提供实际示例,让用户能够更好地理解如何应用这些命令。例如,创建一个带有IN和OUT参数的存储过程,并演示如何调用它,获取输出结果。同时,可以引用之前提到的性能优化建议,比如使用存储过程减少网络延迟,提升效率,如用户之前的问题中提到的本地执行优势。 总结步骤:首先介绍CALL语句的基本语法,然后讲解参数传递方法,包括输入、输出参数的处理,接着给出创建和执行存储过程的完整示例,最后提供相关的注意事项和常用命令,如修改分隔符、查看存储过程等。确保回答覆盖用户可能需要的各个方面,同时结合之前的引用内容,增强回答的准确性和参考价值。</think>以下是MySQL存储过程执行命令的详细说明及操作指南: --- ### **一、存储过程执行核心语法** #### 1. 基础执行命令 ```sql CALL 存储过程名称([参数列表]); ``` 示例:调用无参存储过程 ```sql CALL simple_proc(); ``` #### 2. 参数传递方式 根据参数类型(IN/OUT/INOUT)进行传参: ```sql -- IN参数(输入参数) SET @input_val = 100; CALL in_proc(@input_val); -- OUT参数(输出参数) CALL out_proc(@output_val); SELECT @output_val; -- INOUT参数(双向参数) SET @inout_val = 50; CALL inout_proc(@inout_val); SELECT @inout_val; ``` --- ### **二、完整执行示例** #### 步骤1:创建示例存储过程 ```sql DELIMITER // -- 修改结束符[^1] CREATE PROCEDURE order_analysis( IN min_price DECIMAL(10,2), OUT high_count INT, INOUT total_sum DECIMAL(10,2) ) BEGIN SELECT COUNT(*) INTO high_count FROM orders WHERE amount > min_price; SET total_sum = total_sum + (SELECT SUM(amount) FROM orders); END// DELIMITER ; -- 恢复默认结束符 ``` #### 步骤2:执行存储过程 ```sql -- 准备参数 SET @min = 500.00; SET @sum = 0.00; -- 调用存储过程 CALL order_analysis(@min, @high_cnt, @sum); -- 查看结果 SELECT @min AS 最低标准, @high_cnt AS 高价值订单数, @sum AS 总销售额; ``` --- ### **三、参数类型对照表** | 参数类型 | 数据流向 | 是否必须初始化 | 典型应用场景 | |----------|-----------------|----------------|--------------------| | IN | 客户端→存储过程 | 是 | 查询条件值 | | OUT | 存储过程→客户端 | 否 | 返回统计结果 | | INOUT | 双向传递 | 是 | 累计值计算 | --- ### **四、高级执行技巧** #### 1. 批量结果处理 ```sql -- 创建返回结果集的存储过程 CREATE PROCEDURE get_recent_orders(IN days INT) BEGIN SELECT * FROM orders WHERE order_date > NOW() - INTERVAL days DAY; END; -- 调用并获取结果 CALL get_recent_orders(7); -- 返回最近7天订单 ``` #### 2. 嵌套调用 ```sql CREATE PROCEDURE master_proc() BEGIN CALL sub_proc1(); -- 调用子过程 CALL sub_proc2(); END; ``` #### 3. 错误处理 ```sql DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN GET DIAGNOSTICS CONDITION 1 @err_no = MYSQL_ERRNO, @message = MESSAGE_TEXT; SELECT CONCAT('错误 ', @err_no, ': ', @message); END; ``` --- ### **五、配套管理命令** 1. 查看已有存储过程 ```sql SHOW PROCEDURE STATUS WHERE Db = 'your_db'; -- 列表查看[^4] ``` 2. 查看创建语句 ```sql SHOW CREATE PROCEDURE order_analysis; -- 结构查看 ``` 3. 权限管理 ```sql GRANT EXECUTE ON PROCEDURE db.order_analysis TO 'user'@'host'; ``` --- ### **六、性能优化建议** 1. **参数优化** - 避免在IN参数中传递大文本 - 对OUT参数使用合适的数据类型 2. **执行计划分析** ```sql EXPLAIN ANALYZE CALL critical_proc(); -- 需要MySQL 8.0+支持 ``` 3. **缓存机制** ```sql -- 创建确定性存储过程 CREATE PROCEDURE cached_proc() DETERMINISTIC BEGIN -- 可缓存结果的逻辑 END; ``` --- ### **七、典型错误排查** 1. 参数数量不匹配错误 ```bash Error Code: 1318. Incorrect number of arguments for PROCEDURE ``` 2. 权限不足错误 ```bash Error Code: 1370. execute command denied to user ``` 3. 变量作用域错误 ```bash Error Code: 1328. Undeclared variable: @missing_var ``` --- ### **八、与存储函数的区别** | 特征 | 存储过程 | 存储函数 | |----------------|--------------------------|--------------------------| | 返回值 | 可无或多个OUT参数 | 必须有且仅有一个返回值 | | 调用方式 | CALL | SELECT | | 事务控制 | 支持BEGIN/COMMIT | 不允许 | | 结果集 | 可返回多个结果集 | 只能返回单一值 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值