2011-01-01 13 views
5

私は、MySQL Workbenchで作られた多くのストアドプロシージャを持っています。 MySQL Workbenchを使用してテストDBに入れてもうまく動作します。PHPからMySQLにストアドプロシージャを挿入/作成するには?

私は配備用のDB作成スクリプトを準備していますが、これが私に問題を起こす唯一のものです。コマンドライン/ mysqlシェルを使用すると、スクリプトは完全にうまく動作します。 PHP mysql(i)インターフェースを使用してスクリプトを実行する場合のみです。失敗します。コメントなし。

MySQL Workbenchが私のために生成するように、プロシージャ作成スクリプトを使用します。手順はここ

; 
END$$ 
DELIMITER ; 

このスクリプトを行く...

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

:各手順について繰り返し、スクリプトの開始時に

SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@SQL_MODE, SQL_MODE='TRADITIONAL'; 

:それはそれは、このパターンを持っている、ですMySQL Workbenchから実行するとうまく動作します。私はmysqlコマンドラインから同じものを試してもうまく動作します。しかし、PHPのmysqliインターフェース(mysqli_multi_queryを使って実行すると、他のスクリプトでDBを作成して移植するのに問題ありません)を通して実行すると、何も達成できません。インターフェイスにエラーは返されず、結果(!)はありません。 私が得るのは「偽」です。それだけです。エラーコードは0で、エラーメッセージはありません。

私にとっては大きなWTFだし、正しい方向に向けることができれば幸いです。これを修正してPHPからプロシージャをインストールするにはどうしたらいいですか?

PS:root/adminアクセスが与えられ、検証されました(結局、私はまったく同じ接続、作成されたユーザー、挿入されたテーブルなどでDBを作成しました)。

+0

「dbname」の使用を削除してみます。また、mysqli_queryコマンドを使用している場合は実行してみてください。 – Knubo

+0

USEステートメントを削除しましたが効果はありません。 mysqli_queryも失敗します。この場合、文字列には複数のステートメントが含まれているため、*が正しく実行されていれば、複数の結果が返されます(mysqli_queryは処理しません)。 - 他のスクリプトの場合、mysqli_multi_queryは完全に正常に動作し、各ステートメントに対して1つの結果行を返します。 (成功時は空行、注意:SHOW WARNINGSへの反応として1051行、すべて期待どおり)。 – foo

+0

私は近づいています - 解決策はありませんが、診断です。 DELIMITERはクライアントサイドで実装されているようです(!)。 – foo

答えて

5

私はテストしませんでしたが、私はmysqli_multi_query()で各クエリの同じ区切り文字を使用すると予想しています。 DELIMITER修飾子を使用せずに、ストアドプロシージャの作成を1つのクエリでパックしようとしていますか?

ので、代わりの

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

を行うと、それが動作するかどうかを教え:)

+2

それはうまくいきます。以前に書いたように、DELIMITERはクライアントサイドで実装されているようですが、PHPのmysql(i)インターフェースには、DELIMITERのようにmySQLクライアントが実装するいくつかの部分が欠けているようです。 DELIMITERはまったく実装されていないようです。したがって、DELIMITERを使わずに手順を別々に送信することができます。しかし、私はルーチンを何度も手書き書き換えすることは実行可能な解決策ではないと思います。これは非常に多くのルーチンであり、今後はさらに多くのルーチンが存在します。私は、私が与えた道具で*働く何かが必要です。しかし、アイデアのおかげで、これは他人を助けるかもしれません。 – foo

+1

ありがとう、私はmysqli_multi_queryからストアドプロシージャを作成しようとしている同じ問題を抱えていた、それはHeidiSQLから働いたが、私はPHPから同じコードを実行したときにエラーを投げた。私はDELIMETERステートメントを削除し、改行があれば完全に機能しました。ありがとう! :D – Jared

+0

質問:PHPからstoredProcedureがすでに存在するかどうかを確認する方法? –

-3

DELIMITERは、MySQLクライアントアプリケーションが実際に使用するものです。私は、クライアントアプリケーションがMysqlに送信するクエリを分割する責任があると考えています。これがPHPMyAdminの機能です。

MySQLをクエリに構文解析するためのスクリプトを書くのに一晩を費やす代わりに、私が書いたコードを使用します。あなたはここで、scriptToQueries機能でそれを見つける:

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

EDITをENJOY:https://github.com/EGreg/Platform/blob/master/platform/classes/Db/Mysql.php#L824:この答えを書いて以来、私はあなたがコードを学ぶことのできる無料のQプラットフォームにコードを移植しています

+0

が正しい方向にまっすぐに進みました。ありがとう! – foo

+4

リンクは '.htaccess' /' .htpasswd'パスワード保護ページを参照します。 – automatix

+0

大丈夫よ今しよう –

0

合計:

DELIMITERはサーバー側ではなくクライアント側で実装されています。

ドライバやAPIが優れている場合は、この問題が発生する可能性があります。 PHPのmysql/mysqliは現在のところ、ありません。

異なるデリミタを使用する必要がある場合(たとえば、デフォルトの区切り文字がスクリプト内に表示されるため)、SQLを独自にエンコードまたはエスケープしたり、区切り文字を変更する必要がないように分割する必要があります。 PHPのヘルプはここにありません。

関連する問題