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

foo*_*foo 5 php mysql mysqli stored-procedures mysql-workbench

我有许多使用MySQL Workbench创建的存储过程.当使用MySQL工作台将它们放入我的测试数据库时,它们工作得很好.

现在我正在准备用于部署的数据库创建脚本,这是唯一一个给我带来麻烦的脚本.当我使用命令行/ mysql shell时,脚本可以很好地工作.只有当我使用PHP mysql(i)接口执行脚本时才会失败.没有评论.

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

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';
Run Code Online (Sandbox Code Playgroud)

在脚本的开头,然后重复每个过程:

DELIMITER $$
USE `dbname`$$
CREATE PROCEDURE `procname`(IN inputparameters)
BEGIN
Run Code Online (Sandbox Code Playgroud)

...程序在这里

;
END$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

如果从MySQL Workbench运行,此脚本可以正常工作.如果我从mysql命令行尝试相同的操作它也运行正常.但是当我通过PHP mysqli接口执行它时,它无法完成任何事情(使用mysqli_multi_query执行它,这对于创建和填充数据库的其他脚本工作正常).界面上没有返回错误,没有结果(!).我得到的只是"假",就是这样.错误代码为0,没有错误消息.

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

PS:给出并验证了root/admin访问权限(毕竟,我刚创建了具有相同连接,创建用户,插入表等的DB).

Xav*_*osa 5

我没有测试过,但是我mysqli_multi_query()希望每个查询都有相同的分隔符,我不会感到惊讶.尝试在单个查询中打包存储过程创建,而不使用DELIMITER修饰符?

而不是

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

    ;
    END$$
    DELIMITER ;
');
?>
Run Code Online (Sandbox Code Playgroud)

就这样做吧

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

并告诉我们它是否有效:)

  • 那是有效的.正如我之前写的,DELIMITER似乎是在客户端实现的,而且PHP mysql(i)接口似乎缺少mySQL客户端实现的一些部分 - 比如DELIMITER.它似乎根本没有实现DELIMITER.因此,单独发送程序而不使用DELIMITER.但是,我不认为一次又一次地手动重写例程是一个可行的解决方案.这是一系列惯例,将来会有更多例行公事.我需要的东西可以*使用我给出的工具,而不是再次使用.但是感谢这个想法,这可能对其他人有所帮助. (2认同)

foo*_*foo 1

把它们加起来:

DELIMITER 是在客户端实现的,而不是在服务器端实现的。

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

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