Подтвердить что ты не робот

Что такое значение знака вопроса в 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. Это какой-то держатель параметров?

4b9b3361

Ответ 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