如何在PDO中为不同的表使用相同的预准备语句?

时间:2011-11-11 22:41:09

标签: php pdo prepared-statement

我经常要提交一些非常类似的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)。所以我想我必须寻找另一种解决方案。

2 个答案:

答案 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语句。您能尝试一下吗?