我正在解析一些代码并遇到了这个,
$sql = 'SELECT page.*, author.name AS author, updator.name AS updator ' . 'FROM '.TABLE_PREFIX.'page AS page ' . 'LEFT JOIN '.TABLE_PREFIX.'user AS author ON author.id = page.created_by_id ' . 'LEFT JOIN '.TABLE_PREFIX.'user AS updator ON updator.id = page.updated_by_id ' . 'WHERE slug = ? AND parent_id = ? AND (status_id='.Page::STATUS_REVIEWED.' OR status_id='.Page::STATUS_PUBLISHED.' OR status_id='.Page::STATUS_HIDDEN.')';
我想知道什么是"?" 在WHERE语句中.它是某种参数持有者吗?
准备好的语句使用'?' 在MySQL中允许绑定params到语句.如果使用得当,高度认为对SQL注入更安全.这也允许更快的SQL查询,因为请求只需编译一次并可以重用.
问号表示稍后将被替换的参数.使用参数化查询比将参数直接嵌入查询更安全.
SQL Server调用此参数化查询,Oracle调用它绑定变量.
用法因您执行查询的语言而异.
以下是PHP如何使用它的示例.
假设这$mysqli
是一个数据库连接,并且people
是一个包含4列的表.
$stmt = $mysqli->prepare("INSERT INTO People VALUES (?, ?, ?, ?)"); $stmt->bind_param('sssd', $firstName, $lastName, $email, $age);
这'sssd'
是一个标识其余参数的标志,其中s
表示字符串并d
表示数字.
?
在MySQL WHERE =
语句中没有特殊含义
它对于几个外部接口(如PHP stdlib和Web框架,如Rails)只有特殊含义.
?
只是一个语法错误:
CREATE TABLE t (s CHAR(1)); SELECT * FROM t WHERE s = ?;
因为它没有引用,并且在:
INSERT INTO t VALUES ('a'); INSERT INTO t VALUES ("?"); SELECT * FROM t WHERE s = '?';
它返回:
s ?
因此显然没有特别的意义.
Rails示例
例如,在Rails中,问号由库的编程语言(Ruby)的变量给出的参数替换,例如:
Table.where("column = ?", "value")
并自动引用参数以避免错误和SQL注入,生成如下语句:
SELECT * FROM Table WHERE column = 'value';
引用会在以下情况下保存我们:
Table.where("column = ?", "; INJECTION")
MySQL 5.0编写的语句
MySQL 5.0添加了预准备语句功能,该功能与Web框架中的问号具有相似的语义.
来自文档的示例:
PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; SET @a = 3; SET @b = 4; EXECUTE stmt1 USING @a, @b;
输出:
hypotenuse 5
这些也可以按预期转义特殊字符:
PREPARE stmt1 FROM 'SELECT ? AS s'; SET @a = "'"; EXECUTE stmt1 USING @a;
输出:
s '