Я создаю динамический запрос 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-запрос






Я не уверен, что стоит заморачиваться со всеми этими проблемами, потому что не проще ли просто запустить этот запрос:
$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, без конкатов, без подготовки и без дополнительного обращения к базе данных.
И даже на общий вопрос «Как выполнить запрос из переменной mysql с помощью PDO» ответ: «выберите эту глупую переменную и используйте строку, которую она возвращает в запросе/подготовьте обычным способом».
Но... почему бы вам просто не выбрать *, а затем отказаться от ключа pri в PHP, если по какой-то странной причине он не нужен? И все же, если вы хотите получить имена строго из схемы, почему бы вам не объединить их в PHP? Что проще, быстрее и удобнее? И, в конце концов, вы можете просто выбрать переменную SQL и затем использовать ее как обычный запрос с PDO.