在"WHERE column =?"中,问号在MySQL中的意义是什么?

Lev*_*evi 39 mysql syntax

我正在解析一些代码并遇到了这个,

$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.')';
Run Code Online (Sandbox Code Playgroud)

我想知道什么是"?" 在WHERE语句中.它是某种参数持有者吗?

Jay*_*rox 36

准备好的语句使用'?' 在MySQL中允许绑定params到语句.如果使用得当,高度认为对SQL注入更安全.这也允许更快的SQL查询,因为请求只需编译一次并可以重用.


Ste*_*man 28

问号表示稍后将被替换的参数.使用参数化查询比将参数直接嵌入查询更安全.

SQL Server调用此参数化查询,Oracle调用它绑定变量.

用法因您执行查询的语言而异.

以下是PHP如何使用它的示例.

假设这$mysqli是一个数据库连接,并且people是一个包含4列的表.

$stmt = $mysqli->prepare("INSERT INTO People VALUES (?, ?, ?, ?)");

$stmt->bind_param('sssd', $firstName, $lastName, $email, $age);
Run Code Online (Sandbox Code Playgroud)

'sssd'是一个标识其余参数的标志,其中s表示字符串并d表示数字.


Cir*_*四事件 8

?在MySQL WHERE =语句中没有特殊含义

它对于几个外部接口(如PHP stdlib和Web框架,如Rails)只有特殊含义.

? 只是一个语法错误:

CREATE TABLE t (s CHAR(1));
SELECT * FROM t WHERE s = ?;
Run Code Online (Sandbox Code Playgroud)

因为它没有引用,并且在:

INSERT INTO t VALUES ('a');
INSERT INTO t VALUES ("?");
SELECT * FROM t WHERE s = '?';
Run Code Online (Sandbox Code Playgroud)

它返回:

s
?
Run Code Online (Sandbox Code Playgroud)

因此显然没有特别的意义.

Rails示例

例如,在Rails中,问号由库的编程语言(Ruby)的变量给出的参数替换,例如:

Table.where("column = ?", "value")
Run Code Online (Sandbox Code Playgroud)

并自动引用参数以避免错误和SQL注入,生成如下语句:

SELECT * FROM Table WHERE column = 'value';
Run Code Online (Sandbox Code Playgroud)

引用会在以下情况下保存我们:

Table.where("column = ?", "; INJECTION")
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

输出:

hypotenuse
5
Run Code Online (Sandbox Code Playgroud)

这些也可以按预期转义特殊字符:

PREPARE stmt1 FROM 'SELECT ? AS s';
SET @a = "'";
EXECUTE stmt1 USING @a;
Run Code Online (Sandbox Code Playgroud)

输出:

s
'
Run Code Online (Sandbox Code Playgroud)