我创建了一个测试数据库,如下所示:
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
答案 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',因为你处理的是整数,而不是字符串。