PHP存储过程参数

时间:2013-03-10 07:39:55

标签: php mysql stored-procedures mysqli

我创建了一个测试数据库,如下所示:

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";
}

?>

我的问题是似乎没有调用存储过程。这是由于使用OUTINOUT参数吗?如果是这样,你如何在PHP中使用这些参数?

生成以下输出的脚本

证明了这一点
Connected
In: 0 Out: -1: Inout: 3
End of SP
In: 0 Out: 0: Inout: 0

3 个答案:

答案 0 :(得分:1)

  

<强> CALL Syntax

     

对于用提供MySQL接口的语言编写的程序,   没有直接检索OUT结果的本机方法   或来自CALL语句的INOUT参数。要获取参数值,   将用户定义的变量传递给CALL语句中的过程   然后执行SELECT语句以生成包含的结果集   变量值。要处理INOUT参数,请执行语句   在CALL之前,将相应的用户变量设置为   要传递给程序的值。

在MySQL 5.6中似乎有所改变

  

在MySQL 5.6中,C程序可以使用prepared-statement接口   执行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)
                        ^

答案 1 :(得分:1)

我认为$s->bind_param('sss', $in, $inout, $out);应该是

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

答案 2 :(得分:0)

'sss'应该是'iii',因为你处理的是整数,而不是字符串。