2011-11-11 74 views
0

我經常需要提交一些非常相似的SQL查詢,例如刪除我知道ID的表中的一行。這是我與prepared statement一段代碼:如何在PDO中爲不同的表使用相同的預備語句?

$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子句

我剛讀到我不能使用準備表或列名稱的報表(source)。所以我想我必須尋找另一個解決方案。

+0

如果你嘗試運行它,會發生什麼? – NullUserException

+0

什麼都沒有。我已經添加了一些行以顯示給你儘可能多的關於這個「bug」的信息。我認爲這是故意無法替換表名稱,因爲準備好的語句似乎存儲在數據庫中進行優化......據我所知。我想可能很難爲每張桌子同時做到這一點。所以我希望我會爲預先準備好的陳述找到一個替代方案,或者告訴我我對他們的假設是錯誤的。 –

回答

1

我覺得(我不是100%肯定這個),您試圖查詢表叫

`'TableName'` 

或者

`"TableName"` 

取決於PDO如何試圖引用您的參數。我一直在尋找如何不引用PDO中的字符串(我有你的同樣的問題),但我放棄了很久以前,並寫了我自己的實現。

也許你可以預先處理查詢和替換的參數和表名,注意在陷阱That's what I'm talking about),而代表PARAM名稱可能發生。

+0

感謝您提供此信息。我查看了MySQL服務器收到的查詢:SELECT user_password FROM'chess_users'WHERE 1 ='1''。這似乎是我無法用準備好的陳述來做的原因。另一個有趣的觀察:這個查詢是由'SELECT user_password FROM:table WHERE:uid =:uid'創建的。爲什麼:uid一次被1替換,一次被'1'替換? –

+0

我對此沒有把握,您在綁定uid參數時使用了哪種引用? – Minkiele

+0

我不確定你的意思是「報價類型」。我已經使用了這個綁定語句(一次):'$ stmt-> bindValue(':uid',USER_ID,PDO :: PARAM_INT);'和USER_ID在PDO語句前後是'int'。我用'var_dump'檢查過。 –

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 
    // ... 
    // ... 
    // ... 
} 

這裏你只是去通過使用表和要建立你DELETE SQL語句ID數組循環..你能不能讓這個嘗試?

相關問題