我正在创建动态 mysql 查询,其中我需要选择除主键列之外的 * 列。然后,我需要使用 pdo 在 php 中获取该列的数据。
$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 查询
您定义了一个名为
@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);