php - 使用 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
; CALLsp1
(@p0, @p1)' 附近使用正确的语法”
任何帮助将非常感激!
解决方案
里面有什么$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 个。这将如何解析?
推荐阅读
- node.js - 无服务器节点 TypeScript 应用程序无法导入模块
- angular - 将响应字符串解析为 Angular2+ 中的对象
- apache - httpd 反向代理后面的 Keycloak SSL
- bash - bash - 使用正则表达式用户选项查找命令
- mongodb - 将 find() 的结果保存到另一个集合
- rust - 拥有价值的矛盾“缺少生命周期说明符”错误
- c++ - 使用 WindowsCreateStringReference 与 WindowsCreateString 取消分配 HSTRING
- ruby-on-rails - 块不删除记录之前的Rspec 3.8
- angular - 角度 6 动画不适用于 ngswitch
- python - 动态值网页抓取