如何从PHP在mySQL中插入/创建存储过程?

如何从PHP在mySQL中插入/创建存储过程?,php,mysql,stored-procedures,mysqli,mysql-workbench,Php,Mysql,Stored Procedures,Mysqli,Mysql Workbench,我用MySQL工作台制作了许多存储过程。当使用MySQL工作台将它们放入我的测试数据库时,它们工作得很好 现在我正在为部署准备DB创建脚本,这是唯一一个给我带来麻烦的脚本。当我使用命令行/mysql shell时,该脚本可以很好地用于。只有当我使用PHP mysql(I)接口执行脚本时,它才会失败。无可奉告 我使用MySQL workbench为我生成的过程创建脚本;也就是说,它有这样的模式: SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHEC

我用MySQL工作台制作了许多存储过程。当使用MySQL工作台将它们放入我的测试数据库时,它们工作得很好

现在我正在为部署准备DB创建脚本,这是唯一一个给我带来麻烦的脚本。当我使用命令行/mysql shell时,该脚本可以很好地用于。只有当我使用PHP mysql(I)接口执行脚本时,它才会失败。无可奉告

我使用MySQL workbench为我生成的过程创建脚本;也就是说,它有这样的模式:

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
在脚本开始处,然后对每个过程重复:

DELIMITER $$
USE `dbname`$$
CREATE PROCEDURE `procname`(IN inputparameters)
BEGIN
。。。程序在这里

;
END$$
DELIMITER ;
如果从MySQL工作台运行,该脚本工作正常。如果我从mysql命令行尝试同样的方法,它也可以正常运行。但是,当我通过PHP mysqli接口执行它时,它没有完成任何事情(使用mysqli_multi_查询执行它,这对于创建和填充数据库的其他脚本来说很好)。界面上没有返回错误,没有结果(!)。 我得到的只是“假”,仅此而已。错误代码为0,没有错误消息

这对我来说是一个很大的WTF,我希望你能给我指出正确的方向——我如何修复这个问题并从PHP安装程序


PS:root/admin访问权是被授予和验证的(毕竟,我只是用非常相同的连接创建了DB,创建了用户,插入了表等等)。

我还没有测试过,但是我不会惊讶于
mysqli\u multi\u query()
希望每个查询都有相同的分隔符。 是否尝试在单个查询中打包存储过程创建,而不使用分隔符修饰符

所以不是

<?php
$results = mysqli_multi(
    'DELIMITER $$
    USE `dbname`$$
    CREATE PROCEDURE `procname`(IN inputparameters)
    BEGIN
    ... procedure goes here

    ;
    END$$
    DELIMITER ;
');
?>

就这么做吧

<?php
$result = mysqli_query('CREATE PROCEDURE `procname`(IN inputparameters) BEGIN ...; END');

分隔符是mysql客户端应用程序实际使用的东西。我相信客户端应用程序负责分解发送给Mysql的查询。例如,PHPMyAdmin就是这样做的

使用我编写的代码,而不是花一整晚的时间编写脚本来将MySQL解析为查询。您可以在scriptToQueries函数中找到它,如下所示:

享受

编辑:自从写下这个答案后,我已经将代码移植到免费Q平台中,您可以在其中学习代码:

总结一下:

分隔符是在客户端而不是服务器端实现的

如果您有一个好的驱动程序或API,它可能会解决这个问题。 到目前为止,PHP-mysql/mysqli还没有实现


如果需要使用不同的分隔符(例如,因为默认分隔符出现在脚本中),则必须自己对SQL进行编码/转义,或者将其分解,这样就不需要更改分隔符。这里没有PHP的帮助。

请尝试删除“dbname”的用法。如果使用mysqli_query命令,还可以尝试运行if。我确实删除了USE语句,没有效果。mysqli_查询也失败了——在本例中,原因很明显:字符串包含多个语句,因此如果执行正确,它将返回多个结果——mysqli_查询不会处理这些结果。-对于其他脚本,mysqli_multi_查询工作得非常好,每个语句返回一个结果行。(成功时空行,注意:1051行作为显示警告的反应;-一切如预期)。我越来越近了-没有解决方案,只有诊断。分隔符似乎是在客户端(!)实现的。是否使用双引号字符串指定查询?PHP可能将
$
作为一个变量来使用。不,它们存储在字符串中,我直接从文件中读取,并检查了$$replacement。这样就可以了。正如我之前所写的,DELIMITER似乎是在客户端实现的,而PHP mysql(I)接口似乎缺少mysql客户端实现的一些部分,比如DELIMITER。它似乎根本没有实现分隔符。因此,单独发送过程并且不使用分隔符是可行的。然而,我不认为一次又一次地手工重写例程是一个可行的解决方案。这是一个相当多的例行程序,并将有更多的在未来。我需要的是能和我得到的工具一起工作的东西,而不是一次又一次。但是谢谢你的想法,这可能会帮助其他人。谢谢你,我也遇到了同样的问题,试图从mysqli_multi_query创建并执行一个存储过程,它在HeidiSQL中工作,但是当我从PHP执行相同的代码时,它抛出了一个错误。我删除了DELIMETER语句和任何换行符,它工作得非常好。谢谢DQUOTE:如何从PHP检查storedProcedure是否已经存在?@MikeWarren:SHOW PROCEDURE STATUS提供了存储过程的列表。该链接引用了一个
.htaccess
/
.htpasswd
密码保护页面。