Что такое значение знака вопроса в MySQL в столбце WHERE =??
Я разбираю какой-то код и наткнулся на это,
$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. Это какой-то держатель параметров?
Ответы
Ответ 1
Подготовленные записи используют '?' в MySQL, чтобы обеспечить привязку параметров к инструкции. При правильном использовании он считается более защищенным от инъекций SQL. Это также позволяет быстрее запрашивать SQL-запросы, поскольку запрос должен быть скомпилирован один раз и может быть повторно использован.
Ответ 2
Значок вопроса представляет собой параметр, который позже будет заменен. Использование параметризованных запросов более безопасно, чем встраивание параметров прямо в запрос.
SQL Server вызывает эти параметризованные запросы, а Oracle вызывает переменные bind.
Использование зависит от языка, из которого выполняется запрос.
Вот пример того, как он используется с PHP.
предполагая, что $mysqli
- это соединение с базой данных, а people
- таблица с 4 столбцами.
$stmt = $mysqli->prepare("INSERT INTO People VALUES (?, ?, ?, ?)");
$stmt->bind_param('sssd', $firstName, $lastName, $email, $age);
'sssd'
- это флаг, идентифицирующий остальные параметры, где s
представляет строку и d
представляет цифры.
Ответ 3
None
?
ничего не значит для предложения MySQL WHERE =
, только для нескольких внешних интерфейсов, таких как PHP stdlib и веб-фреймворки, такие как 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 добавила готовую функцию оператора, которая имеет сходную семантику с вопросительным знаком в веб-фреймворках.
Пример из документов:
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
'
Ответ 4
Это подготовленные заявления, подготовленные заявления предлагают два основных преимущества:
Запрос нужно только разобрать (или подготовить) один раз, но может быть выполняются несколько раз с одинаковыми или разными параметрами. когда запрос готов, база данных будет анализировать, компилировать и оптимизировать его план выполнения запроса. Для сложных запросов этот процесс может занимать достаточно времени, чтобы заметно замедлить приложение если есть необходимость повторять один и тот же запрос много раз с разными параметры. Используя подготовленное выражение, приложение избегает повторяя цикл анализа/компиляции/оптимизации. Это означает, что подготовленный операторы используют меньше ресурсов и тем самым работают быстрее.
Параметры для подготовленных операторов не обязательно должны быть указаны; драйвер автоматически обрабатывает это. Если приложение использует исключительно подготовленные заявления, разработчик может быть уверен, что SQL-инъекция (однако, если другие части запроса будут созданы с несвязанным вводом, SQL-инъекция по-прежнему возможна).
http://php.net/manual/en/pdo.prepared-statements.php