6

我有许多用 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';

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

DELIMITER $$
USE `dbname`$$
CREATE PROCEDURE `procname`(IN inputparameters)
BEGIN

...程序在这里

;
END$$
DELIMITER ;

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

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

PS:root/admin 访问权限已提供并验证(毕竟,我刚刚使用相同的连接创建了数据库,创建了用户,插入了表等等)。

4

3 回答 3

7

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

所以而不是

<?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');

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

于 2011-01-16T11:44:06.777 回答
1

把它们加起来:

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

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

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

于 2014-02-19T13:26:06.517 回答
-3

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

与其花一整夜编写脚本来将 MySQL 解析为查询,不如使用我编写的代码。你可以在 scriptToQueries 函数中找到它,这里:

http://wush.net/svn/luckyapps/pie/trunk/framework/classes/Db/Mysql.php

请享用

编辑:自从写了这个答案,我已经将代码移植到免费的 Q 平台中,您可以在其中研究代码:https ://github.com/Ereg/Platform/blob/master/platform/classes/Db/Mysql.php# L824

于 2011-02-17T06:25:38.620 回答