我经常要提交一些非常类似的SQL查询,例如删除表中我知道ID的一行。这是我的代码prepared statement:
$stmt = $conn->prepare("DELETE FROM `".MY_FIRST_TABLE."` WHERE `id` = :id LIMIT 1");
$stmt->bindValue(':id', $id1, PDO::PARAM_INT);
$stmt->execute();
$stmt = $conn->prepare("DELETE FROM `".MY_SECOND_TABLE."` WHERE `id` = :id LIMIT 1");
$stmt->bindValue(':id', $id2, PDO::PARAM_INT);
$stmt->execute();
我想做这样的事情:
$stmt = $conn->prepare("DELETE FROM `:table` WHERE `id` = :id LIMIT 1");
$stmt->bindValue(':id', $id1, PDO::PARAM_INT);
$stmt->bindValue(':table', MY_FIRST_TABLE);
$stmt->execute();
$stmt->bindValue(':id', $id2, PDO::PARAM_INT);
$stmt->bindValue(':table', MY_SECOND_TABLE);
$stmt->execute();
如果我试试这个,没有任何反应。所以我使用以下代码片段来分析错误:
print_r($conn->errorInfo());
var_dump($stmt);
$stmt->debugDumpParams();
我得到了:
Array
(
[0] => 00000
[1] =>
[2] =>
)
object(PDOStatement)#4 (1) {
["queryString"]=>
string(45) "DELETE FROM `:table` WHERE `id` = :id LIMIT 1"
}
SQL: [45] DELETE FROM `:table` WHERE `id` = :id LIMIT 1
Params: 2
Key: Name: [3] :id
paramno=-1
name=[3] ":id"
is_param=1
param_type=1
Key: Name: [6] :table
paramno=-1
name=[6] ":table"
is_param=1
param_type=2
这样的事情可能吗?
(我目前仅出于安全原因使用预准备语句,而不是出于性能原因。)
准备好的陈述和IN-Clause
我刚才读到我不能对表名或列名使用预准备语句(source)。所以我想我必须寻找另一种解决方案。
答案 0 :(得分:1)
我认为(我不是100%确定这一点)您正在尝试查询名为
的表`'TableName'`
或者
`"TableName"`
取决于PDO如何引用您的参数。我一直在寻找如何不在PDO中引用字符串(我有同样的问题),但我很久以前放弃了并编写了我自己的实现。
也许你可以预先处理查询并用一个表名替换一个参数,小心点 gotchas (That's what I'm talking about),这可能会在替换table param name时发生。< / p>
答案 1 :(得分:0)
我可以建议采用不同的方法吗? :
# I'm hard-coding the values so just handle that first and set $id1 and $id2
$parameterArray = array('MY_FIRST_TABLE' => $id1, 'MY_SECOND_TABLE' => $id2);
$sql = '';
foreach($parameterArray as $tableNameKey => $idValue) {
# build sql
$sql = "DELETE FROM `". $tableNameKey ."` WHERE `id`=". $idValue ." LIMIT 1";
# prepare and execute
$stmt = $conn->prepare($sql);
$stmt->execute();
# processing code after execution goes here
// ...
// ...
// ...
}
在这里,您只需使用一组表和ID来进行循环,您可以从中创建DELETE
sql语句。您能尝试一下吗?