переменная привязки для drop table php

#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 и удалять из нее строки, а не таблицы.