#php #mysql #variables #binding
#php #mysql #переменные #привязка
Вопрос:
Я пишу PHP-скрипты для использования с моей базой данных MySQL. Единственная проблема, с которой я сталкиваюсь, — это привязка переменных для drop table / create table и так далее.
$stmt = $link->prepare("DROP TABLE ?");
$stmt->bind_param('s','testing');
$stmt->execute();
не работает. Я пытался также:
SELECT * FROM (SELECT MAX(name) from profiles where name='testing') <- is working
DROP TABLE (SELECT MAX(name) from profiles where name='testing') <- dont work
Ответ №1:
Привязка параметра — это не то же самое, что просто замена части строки: вы не можете просто привязать все, что хотите.
В этом случае: вы не можете использовать связанный параметр для имени таблицы — вам придется использовать конкатенации строк для построения вашего запроса, вместо использования подготовленного оператора.
В качестве ссылки, цитирующий PREPARE
синтаксис :
Маркеры параметров можно использовать только там, где должны отображаться значения данных, а не для ключевых слов SQL, идентификаторов и так далее.
Ответ №2:
Насколько я знаю, вы можете привязываться только к параметру, а не к какой-либо части запроса, которую вы хотите. По сути, вы говорите базе данных: «Эй, я собираюсь передать вам здесь значение, и я хочу, чтобы вы применили свое волшебство, чтобы убедиться, что оно не выходит за свои пределы». Такие вещи, как имена таблиц или полей, не являются значениями, они являются частью самой структуры таблицы.
В этом случае вам придется просто использовать a use a simple $query = "DROP TABLE " . $table;
. Должно быть достаточно легко проверить список известных таблиц, чтобы убедиться, что вы не вводите ничего вредоносного. Насколько я понимаю, все, что вносит изменения в DDL, в любом случае не должно принимать входные данные от пользователя. Такого рода изменения могут быть основаны на пользовательском вводе, но фактическая конструкция запроса должна быть действительно хорошо известна и для ее построения не должны требоваться внешние данные.
Кроме того, я не совсем уверен, что вы пытаетесь сделать с этим запросом:
DROP TABLE (SELECT MAX(name) from profiles where name='testing');
Похоже, вы пытаетесь удалить запись, но это совершенно неправильный синтаксис для этого. Если вы пытаетесь удалить таблицу, имя которой происходит из результата другого запроса, я действительно не думаю, что вы сможете это сделать. Я на 99% уверен, что DROP TABLE
ожидает только буквальное значение имени таблицы.
Комментарии:
1. Возможно, это плохой дизайн. У меня было 2 таблицы — изображения и профили. Каждое изображение может быть присвоено одному или нескольким профилям. Поскольку у меня будет ~ 1000 изображений и всего ~ 20 профилей, для целей оптимизации я не хотел создавать таблицу imagexprofile, где я бы связывал оба идентификатора вместе (image1 переходит в profile 1, image1 переходит в profile3, image2 переходит в profile3 и т.д.). Но я думаю, что вернусь к этой идее и вместо этого буду использовать индексы.
2. @Thomas Нет ничего плохого в создании таблицы ProfileImages (личные предпочтения в отношении имени, поскольку profile является доминирующей таблицей в этих отношениях). Я предполагаю, что это отношение «многие ко многим» (т. Е. Одно изображение может использоваться в нескольких профилях, а в одном профиле может быть несколько изображений)? То, как вы это описываете, звучит так, как будто у профиля будет только одно изображение. Если это так, то у вас должен быть просто внешний ключ в вашей таблице profiles, ссылающийся на поле id вашей таблицы images.
Ответ №3:
Вы уверены, что хотите удалять таблицы динамически?
Это крайне необычно.
Кажется, у вас неправильный дизайн базы данных.
И теперь вы столкнулись с последствиями.
Кажется, у вас должна быть одна таблица users
и удалять из нее строки, а не таблицы.