MYSQL本身的限制,不允许在函数和触发器中使用动态语句PREPARE参考手册中红字部分。

解决方案 »

  1.   

    大大,我是在procedure中使用prepare,然后在函数中调用的存储过程,并没有显式的在function中使用,这样也不行吗?难道function调用存储过程的时候是直接把存储过程的内容拷贝到了function中后再执行的?
      

  2.   

    不行。 FUNCTION本身中就禁止PREPARE执行。不管你写在哪儿。
      

  3.   

    我的是5.5可以 ,你的是什么版本 
    mysql> delimiter $
    mysql> CREATE PROCEDURE test_procedure()
        -> BEGIN
        -> create TABLE if not EXISTS temp_table(
        -> id int,
        -> columnname varchar(20)
        -> );
        -> END
        -> $
    Query OK, 0 rows affected (0.01 sec)mysql> CREATE PROCEDURE p_drop_table(temp_tablename varchar(20))
        -> BEGIN
        -> SET @SQLSTR = CONCAT('DROP TABLE IF EXISTS ', temp_tablename, ";");
        -> PREPARE STMT FROM @SQLSTR;
        -> EXECUTE STMT;
        -> DROP PREPARE STMT;
        -> END
        -> $
    Query OK, 0 rows affected (0.00 sec)mysql> CREATE FUNCTION test_function(idValue INT, columnName VARCHAR(20))
        -> RETURNS INT
        -> BEGIN
        -> CALL p_drop_temp_table('temp_table');
        -> CALL temp_procedure();
        -> INSERT INTO temp_table VALUES (idValue, columnName);
        -> RETURN idValue;
        -> END;
        -> $
    Query OK, 0 rows affected (0.00 sec)mysql> SELECT test_function(123, '456');
        -> $
      

  4.   

    你这样做是不允许的....即使把DROP 语句放到存储过程中,然后函数调用存储过程的方式,MySQL也是不允许的....从你想实现的功能,看你编写的函数,就是存储过程需要做的事情,改成存储过程就可以了...推荐:
    淘宝和阿里巴巴去Oracle化事件 引发数据库技术人员大讨论WebGame行业案例:in子查询group by引发的“血案”
      

  5.   

    版主,我挖个坟,问一下,function中调用了proc,proc中有创建和删除临时表,为什么报
    [Err] 1422 - Explicit or implicit commit is not allowed in stored function or trigger.
    如果不能再function中创建删除临时表(或嵌套执行),那有什么好方案来变相实现吗?
    我这里正在做的是split字符串,思路是通过一个proc,将参数和分隔符通过临时表切割,在function中有需要的地方先call一次proc,然后游标临时表。有啥别的办法吗??
      

  6.   

    版主,我挖个坟,问一下,function中调用了proc,proc中有创建和删除临时表,为什么报
    [Err] 1422 - Explicit or implicit commit is not allowed in stored function or trigger.
    如果不能再function中创建删除临时表(或嵌套执行),那有什么好方案来变相实现吗?
    我这里正在做的是split字符串,思路是通过一个proc,将参数和分隔符通过临时表切割,在function中有需要的地方先call一次proc,然后游标临时表。有啥别的办法吗??
    找到办法了,原因是,我的proc中drop了临时表。所以fun调用这个proc依旧会err 1422 。解决办法是,不要drop临时表,不要truncate 临时表,这俩都属于DDL语句,且都会隐式commit(truncate 这个我不知道,有点出乎意料,后来查找相关资料才明白)。使用delete来清理临时表即可。
    但我遇到另外一个问题,在一条sql中嵌套调用了fun(如fun_1(fun_2())这种方式),1和2共同使用了一个porc,里边有个临时表的创建和使用。1和2都对临时表进行了查询操作。报错[Err] 1137 - Can't reopen table:
    为什么嵌套的fun也会报reopen?又不是一条query的2次访问临时表。