首页 > 解决方案 > 使用 PHP 使用 LIMIT 调用参数化 MariaDB SP 时出现问题

问题描述

我对此感到困惑,在任何地方都找不到工作示例或教程。

给定以下存储过程:

SQL

delimiter $$
CREATE PROCECURE sp1(IN 'myoffset' INT, IN 'myrows' 
INT)
begin
select * from t1
limit 'myoffset', 'myrows'
END$$
delimiter

我试图从 PHP 中调用它,如下所示:

...建立$conn,然后

PHP

// ver1:
$sql = ( "SET @p0 = $tmp1;" . " SET @p1 = $tmp2;" . " 
CALL `sp1`(@p0, @p1);" );

//OR    

//ver2
$sql = "SET @p0 = `$tmp1`; SET @p1 = `$tmp2`; CALL 
`sp1`(@p0, @p1);";

$result = mysqli_query($conn, $sql);

两者都不起作用。MariaDB 抱怨说

“错误描述:您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本相对应的手册,以在第 2 行的 'SET @p1 = 25; CALL sp1(@p0, @p1)' 附近使用正确的语法”

任何帮助将非常感激!

标签: phpstored-proceduresmariadb

解决方案


里面有什么$tmp1

如果它是一个数字,那么第一个应该可以工作,但第二个没有意义,因为它变成了

SET @p0 = `1234`;

我假设没有名为的列或表1234?请记住,反引号用于列、表和数据库名称。

如果 $tmp 是字符串"a string",那么你会得到

SET @p0 = a string;  -- strings need to be quoted here

或者

SET @p0 = `a string`;  -- again that is treated as a column (etc) name.

之后,您还有另一个问题:不要将多个语句放在一起(用 分隔;);分别运行它们。

最后,不需要@p0等:

$sql = "CALL `sp1`('$tmp1', '$tmp2')";

足够了。

嗯,不完全是。如果 $tmps 的值来自外部世界,请参阅可怕的“SQL 注入”问题。

哦,如果

$tmp1 = "Don't do this";

然后你得到

$sql = "CALL `sp1`('Don't do this', '$tmp2')";

看单引号。其中有 3 个。这将如何解析?


推荐阅读