Php pdo выполняет запрос из переменной mysql

Я создаю динамический запрос MySQL, в котором мне нужно выбрать * столбец, кроме столбца первичного ключа. Затем мне нужно получить данные этого столбца в php, используя pdo.

$qry_getData = "SELECT
               GROUP_CONCAT(COLUMN_NAME)FROM
              information_schema. COLUMNS WHERE
               TABLE_SCHEMA = 'db1'AND 
               TABLE_NAME = 'books' AND 
               COLUMN_KEY <> 'PRI' INTO @columnName;";
$stmt_getData   =$conn->prepare($qry_getData);
$stmt_getData->execute();

$qry_getData = "SET @query=CONCAT('SELECT ', @columnName , ' FROM `books`');";
$stmt_getData   =$conn->prepare($qry_getData);
$stmt_getData->execute();

$qry_getData = "SELECT @query";
$stmt_getData   =$conn->prepare($qry_getData);
$stmt_getData->execute();
$data_getData   =$stmt_getData->fetchAll(PDO::FETCH_ASSOC);

выход:

array(1) {
 [0]=>
  array(1) {
    ["@query"]=>
      string(70) "SELECT ColA,ColB,ColC,ColD FROM `books`"
  }
 }

Я ожидаю данных из этого столбца в качестве вывода. Но он выводит созданный SQL-запрос

Но... почему бы вам просто не выбрать *, а затем отказаться от ключа pri в PHP, если по какой-то странной причине он не нужен? И все же, если вы хотите получить имена строго из схемы, почему бы вам не объединить их в PHP? Что проще, быстрее и удобнее? И, в конце концов, вы можете просто выбрать переменную SQL и затем использовать ее как обычный запрос с PDO.

Your Common Sense 10.10.2023 08:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
1
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не уверен, что стоит заморачиваться со всеми этими проблемами, потому что не проще ли просто запустить этот запрос:

$qry_getData     = "SELECT * FROM `books`";
$stmt_getData   =$conn->query($qry_getData);
$data_getData   =$stmt_getData->fetchAll(PDO::FETCH_ASSOC);

Но я отвечу на заданный вами вопрос, полагая, что у вас есть веская причина исключить столбец первичного ключа из результата.

Почему в результате вы получили сам запрос, а не данные, которые этот запрос мог бы получить?

Вы определили строковую переменную с именем @query и затем выбрали эту переменную. Тот факт, что он содержит строку, являющуюся запросом SQL, не имеет значения; это все еще просто строковое значение.

Как получить то, что вы хотели, то есть результат всех столбцов этой таблицы, кроме столбца первичного ключа?

Чтобы выполнить эту переменную как строку, вы можете использовать оператор PREPARE. Но для этого требуется больше шагов:

$qry_getData     = "SET @query=CONCAT('SELECT ', @columnName , ' FROM `books`');";
$stmt_getData   =$conn->exec($qry_getData);

$qry_getData     = "PREPARE stmt FROM @query";
$stmt_getData   =$conn->exec($qry_getData);

$qry_getData     = "EXECUTE stmt";
$stmt_getData   =$conn->query($qry_getData);
$data_getData   =$stmt_getData->fetchAll(PDO::FETCH_ASSOC);

$qry_getData     = "DEALLOCATE PREPARE stmt";
$stmt_getData   =$conn->exec($qry_getData);

(В этих случаях нет необходимости использовать PDO::prepare(), поскольку операторы SQL не имеют параметров.)

Технически это SQL-инъекция, поскольку вы не знаете, содержат ли имена столбцов специальные ключевые слова, знаки препинания, пробелы и т. д. Если вы не контролируете имена столбцов, чтобы предотвратить их SQL-инъекцию, вам следует позаботиться о том, чтобы разграничить их.

Затем просто верните запрос и выполните его.

$qry_getData = "SELECT
               GROUP_CONCAT(CONCAT('`', REPLACE(COLUMN_NAME, '`', ''), '`'))FROM
              information_schema. COLUMNS WHERE
               TABLE_SCHEMA = 'db1'AND 
               TABLE_NAME = 'books' AND 
               COLUMN_KEY <> 'PRI' INTO @columnName;";
$rowsAffected   =$conn->exec($qry_getData);

$qry_getData     = "SELECT CONCAT('SELECT ', @columnName , ' FROM `books`') AS `query`;";
$stmt_getData   =$conn->query($qry_getData);
$data_getData   =$stmt_getData->fetchAll(PDO::FETCH_ASSOC);

$stmt->getData  =$conn->query($data_getData["query"]);
$data_getData   =$stmt_getData->fetchAll(PDO::FETCH_ASSOC);

На мой взгляд, вся эта атрибутика SQL не имеет никакого смысла. Поскольку это PHP, можно просто выбрать имена столбцов и создать запрос на PHP. Без переменных SQL, без конкатов, без подготовки и без дополнительного обращения к базе данных.

Your Common Sense 10.10.2023 08:43

И даже на общий вопрос «Как выполнить запрос из переменной mysql с помощью PDO» ответ: «выберите эту глупую переменную и используйте строку, которую она возвращает в запросе/подготовьте обычным способом».

Your Common Sense 10.10.2023 09:06

Другие вопросы по теме