Mysql 执行准备好的语句时,过程以静默方式终止 问题

Mysql 执行准备好的语句时,过程以静默方式终止 问题,mysql,stored-procedures,prepared-statement,Mysql,Stored Procedures,Prepared Statement,我有一个存储过程: 创建过程'problematicsprocedure'(在dbName varchar(50)中,在tableId INT中) 修改SQL数据 开始 下拉视图(如果存在); 下拉视图(如果存在); 调用ExecuteSql(CONCAT(“创建视图v1作为SELECT*FROM”,dbName,“.my_table;””); 调用ExecuteSql(CONCAT(“将视图v2创建为SELECT*FROM”、dbName、.table_1;、tableId、;”)); ...

我有一个存储过程:

创建过程'problematicsprocedure'(在dbName varchar(50)中,在tableId INT中)
修改SQL数据
开始
下拉视图(如果存在);
下拉视图(如果存在);
调用ExecuteSql(CONCAT(“创建视图v1作为SELECT*FROM”,dbName,“.my_table;””);
调用ExecuteSql(CONCAT(“将视图v2创建为SELECT*FROM”、dbName、.table_1;、tableId、;”));
...
当直接从命令行或像Navicat或HeidiSql这样的客户机调用时,运行良好

调用problematicsprocedure(“我的模式”,1);
但是如果使用与上面完全相同的行从自定义Apache模块调用,它将在第一次
ExecuteSql
调用时崩溃。当从Apache模块调用时,我必须让它工作,并且找不到崩溃的原因

ExecuteSql
定义
CREATE PROCEDURE ExecuteSql(在sql\u str文本中)
开始
SET@query=sql\u str;
从@query准备stm;
执行stm;
解除分配准备stm;
结束
我试过什么?
  • 交换了两个
    ExecuteSql
    调用
  • 内联
    ExecuteSql
    调用
  • 删除了
    ExecuteSql
    ,并使用带有硬编码
    dbName
    tableId
    值的直接SQL语句
  • 不带
    的已创建过程修改SQL数据
  • 已授予
    CREATE VIEW
    权限:
    GRANT ALL ON*.*给'myuser'@'
注意:我在两行之间添加了简单的insert语句,以找到崩溃的地方。因此,我确信它总是在第一次调用时崩溃

问题: 这次崩溃的原因是什么?

更新:最后,我设法找到了错误代码:

错误1312:过程无法返回给定上下文中的结果集

解决方案 连接时使用
客户端多语句
标志:

mysql\u real\u connect(conn、host、user、pass、db、0、NULL、CLIENT\u MULTI\u语句);

为什么会这样? 调用存储过程意味着执行多个语句。因此,我需要指定我可以一次执行多个语句。因此,我在客户端(在我的Apache模块中)使用MySql C API函数,在连接时需要指定
客户机多语句
标志:

mysql\u real\u connect(conn、host、user、pass、db、0、NULL、CLIENT\u MULTI\u语句);
或者稍后再设置:

mysql\u set\u server\u选项(mysql\u选项\u多个\u语句\u开启);
我从页面学到了这些


我是如何调试的? 调试存储过程并不是那么容易。我使用了传统的日志表方法,但在查找错误代码时表现得有点咄咄逼人

首先,定义了两个变量来保存发生错误的代码和消息:

声明E INT默认值为0;——错误代码
声明M文本默认为空;--错误消息
然后为和错误()定义可能的错误代码和消息:

为1000 SET声明CONTINUE处理程序E='1000',M=“hashchk”;
声明1001集合的继续处理程序E='1001',M=“isamchk”;
...
...
声明1312集的继续处理程序E='1312',M=“过程%s无法在给定上下文中返回结果集”;
...
...
声明1638 SET的CONTINUE处理程序E='1638',M=“不完全支持非ASCII分隔符参数”;
声明1639集合的继续处理程序E='1639',M=“调试同步点等待超时”;
声明1640的继续处理程序SET E='1640',M=“已达到调试同步点命中限制”;
...
...
DECLARE CONTINUE HANDLER FOR 2057 SET E='2057',M=“结果集中的列数与绑定的缓冲区数不同。必须重置该语句,重新绑定结果集列,然后再次执行该语句”;
最后,将日志置于关键点:

如果E>0,则
调用WriteLog(CONCAT(“Error”,E,“:”,M));
如果结束;

WriteLog
是另一个只插入日志表的过程。这个方法给了我错误代码(
1312
),然后谷歌搜索就成功了。

直接调用时,它也可以在我的机器上运行。版本为
mysql版本14.14发行版5.1.63,对于使用readline 6.2的debian linux gnu(x86_64)和
mysql版本14.14发行版5.1.47,对于Win64(未知)
我想您不需要
修改SQL数据
尝试在没有它的情况下重新创建过程。见: