0

次のようにテストデータベースを作成しました。

USE test;
DROP TABLE IF EXISTS test;
DROP PROCEDURE IF EXISTS testparams;
CREATE TABLE test
(
  inparm INT,
  inoutparam INT,
  outparm INT
);

INSERT INTO test VALUES (0, 0, 0);

DELIMITER $$
CREATE PROCEDURE testparams(IN i INT, INOUT io INT, OUT o INT)
BEGIN
   UPDATE test SET inoutparm = io + 1, outparm = FLOOR(RAND() * 1000)
               WHERE inparm = i; 

   SELECT outparm INTO o FROM test WHERE inparm = i;
   SELECT inoutparam INTO io FROM test WHERE inparm = i;

END $$

私はPHPスクリプトも持っています:

<?php

$c = new mysqli('localhost', 'test', 'test', 'test') or die('Cannot connect');
echo "Connected\n";

$in = 0;
$out = -1;
$inout = 3;

echo "In: $in Out: $out: Inout: $inout\n";

$s = $c->prepare('CALL testparams(?, ?, ?)') or die('Unable to prepare: ' . $c->error);
$s->bind_param('iii', $in, $inout, $out);
#$s->bind_result($out, $inout);
$s->execute();

echo "After execute SP\nIn: $in Out: $out: Inout: $inout\n";

echo "End of SP\n";
$s = $c->prepare('SELECT inparm, inoutparam, outparm FROM test');

# $s->bind_result($in, $inout, $out); - Get a error here

$s->execute();
while ($s->fetch())
{
    echo "In: $in Out: $out: Inout: $inout\n";
}

?>

私の問題は、ストアド プロシージャが呼び出されていないように見えることです。これはパラメータを使用しているためOUTですか?INOUTもしそうなら、これらのパラメータを PHP でどのように使用しますか?

これは、次の出力を生成するスクリプトによって示されます

Connected
In: 0 Out: -1: Inout: 3
End of SP
In: 0 Out: 0: Inout: 0
4

3 に答える 3

1

CALL構文

MySQLインターフェースを提供する言語で記述されたプログラムの場合 、CALLステートメントからOUTまたはINOUTパラメーターの結果を直接取得するためのネイティブメソッドはありません。パラメーター値を取得するには、ユーザー定義変数をCALLステートメントのプロシージャーに渡し、次にSELECTステートメントを実行して、変数値を含む結果セットを生成します。INOUTパラメーターを処理するには、CALLの前に、対応するユーザー変数をプロシージャーに渡される値に設定するステートメントを実行します。

これはMySQL5.6で変更されたようです

MySQL 5.6では、Cプログラムはプリペアドステートメントインターフェイスを使用してCALLステートメントを実行し、OUTおよびINOUTパラメータにアクセスできます。... MySQLインターフェイスを提供する言語は、準備されたCALLステートメントを使用して、OUTおよびINOUTプロシージャパラメータを直接取得できます。

それはそれをします

<?php

$c = new mysqli('localhost', 'test', 'test', 'test') or die('Cannot connect');
echo "<pre>Connected<br>";

$in = 0;
$out = -1;
$inout = 3;

echo "Before executing SP<br>In: $in Inout: $inout Out: $out<br>";

$s = $c->prepare('SET @i = ?, @io = ?') or die('Unable to prepare: ' . $c->error);
$s->bind_param('ii', $in, $inout);
$s->execute();

$s = $c->prepare("CALL testparams(@i, @io, @o)") or die('Unable to prepare: ' . $c->error);
$s->execute();

$s = $c->prepare('SELECT @io, @o');
$s->execute();
$s->bind_result($inout, $out);
$s->fetch();

echo "After execute SP<br>In: $in Inout: $inout Out: $out<br>";

echo "End of SP<br></pre>";

?>

出力

Connected
Before executing SP
In: 0 Inout: 3 Out: -1
After execute SP
In: 0 Inout: 4 Out: 851
End of SP

ところで、SPにはタイプミスがあります。この行

UPDATE test SET inoutparm = io + 1, outparm = FLOOR(RAND() * 1000)

する必要があります

UPDATE test SET inoutparam = io + 1, outparm = FLOOR(RAND() * 1000)
                        ^
于 2013-03-10T08:09:00.177 に答える
1

と思います$s->bind_param('sss', $in, $inout, $out); する必要があります

$s->bind_param('iii', $in, $inout, $out);

于 2013-03-10T08:23:17.023 に答える
0

文字列ではなく整数を扱っているため、「sss」は「iii」にする必要があります。

于 2013-03-10T08:00:00.743 に答える