2011-09-23 82 views
0

我的問題是我無法讓佔位符在我的SQL語句中工作。具體來說,在下面的代碼中,當我用'abcdefg'這樣的值替換佔位符':tripsid'時,TABLE不會按照預期創建。PHP PDO :: prepare() - SQL佔位符錯誤

SQL錯誤是:

PDO :: errorInfo中():陣列([0] => 42000 [1] => 1064 [2] =>你在你的SQL語法 錯誤;檢查對應於您 MySQL服務器版本正確的語法附近* '' sdfghjk '使用手冊(ID INT NOT NULL,stop_start SMALLINT NOT NULL,stop_end SMA' *在1號線)

和代碼:

// My method to create a table with PDO and placeholders 
public function routes_table() { 

    $this->connect(); 

    $STH = $this->DBH->prepare('CREATE TABLE IF NOT EXISTS :tripsid (
     id INT NOT NULL, 
     stop_start SMALLINT NOT NULL, 
     stop_end SMALLINT NOT NULL, 
     distance SMALLINT NOT NULL, 
     duration TINYINT NOT NULL, 
     medium TINYTEXT NOT NULL, 
     CONSTRAINT pk_routes PRIMARY KEY (id) 
     )'); 


    $tripsid = "sdfghjk"; 
    $STH->bindParam(':tripsid', $tripsid, PDO::PARAM_STR, 7); 

    $STH->execute(); 

    // SQL Errors 
    if (!$STH->execute($input)) { 
     echo "\nPDO::errorInfo():\n"; 
     print_r($STH->errorInfo()); 
    } 

    $this->disconnect(); 

} 

我已經嘗試過所有我能想到的。有沒有人看到錯誤?

回答

0

現在好了我知道由PDO :: bindParam()自動綁定到參數的引號引起了問題。沒有任何人有一個想法如何從表名所以我的代碼將被刪除引號...

$STH = $this->DBH->prepare('CREATE TABLE IF NOT EXISTS tablename (
      id INT NOT NULL,... 

,而不是

$STH = $this->DBH->prepare('CREATE TABLE IF NOT EXISTS 'tablename' (
      id INT NOT NULL, 
+0

請務必將其標記爲已接受,如果這確實可以解決您的問題。 –

0

我看到這個問題是一歲,但我只是偶然發現了它,並想強調一些事情:這與引號無關。

當發生錯誤時,您將得到與所討論的語法相關的SQL代碼片段,它會自動圍繞一對單引號引起來。這通常會使它看起來好像有一個不同的問題,即混合使用雙引號和單引號。

在本例中 -

PDO :: errorInfo中():陣列([0] => 42000 1 => 1064 [2] =>你在你的SQL語法錯誤;校驗對應於您的MySQL服務器版本正確的語法手冊近'sdfghjk '使用(ID INT NOT NULL,stop_start SMALLINT NOT NULL,stop_end SMA第1行'

它指的是:

'sdfghjk' (id INT NOT NULL, stop_start SMALLINT NOT NULL, stop_end SMA 

最外面的引號只針對錯誤輸出;像我一樣 - 我擔心你注意到了這一點,並認爲你的錯誤是關於不正確的引號。 這是一隻紅鯡魚!刪除最外面的單引號,以實際查看不正確的SQL。

至於你真正的問題:你不能指定表名(或列名)作爲參數;這在大多數平臺和API上準備好的語句中很常見。這適用於任何查詢 - 選擇/插入/更新等等等 - 它們都不能接受表名作爲參數。欲瞭解更多信息 - 請參閱此question here

考慮到這一點,我會用 sprintf()來實現這樣的事情

所以......

$STH = $this->DBH->prepare(
    sprintf('CREATE TABLE IF NOT EXISTS %s (
     id INT NOT NULL, 
     stop_start SMALLINT NOT NULL, 
     stop_end SMALLINT NOT NULL, 
     distance SMALLINT NOT NULL, 
     duration TINYINT NOT NULL, 
     medium TINYTEXT NOT NULL, 
     CONSTRAINT pk_routes PRIMARY KEY (id) 
     )', $tripsid) 
); 

$STH->execute(); 

是的,它需要相當的美了PDO的時候你還是要處理字符串 - 不幸的是,這是使用表名作爲參數的情況! 此外,請記住,這意味着「老式」SQL注入風險仍然可以適用,因爲您直接操縱查詢。

我不認爲這將有助於OP一年後,但我希望它會幫助別人吧! :)