2011-05-03 72 views
28

UPDATE「無效參數號:沒有定義參數的」插入數據

我正在一個小錯誤列出值時,。我應該把「:用戶名」,而不是「:別名」。我想這個問題的答案是對任何需要它的人來說是免費的嗎?或者我刪除這個問題?

ORIGINAL

我一直在使用Yii的活動記錄圖形一會兒。現在,我的項目需要爲一個小事務訪問不同的數據庫。我認爲Yii的DAO對此會有好處。但是,我收到了一個神祕的錯誤。

CDbCommand未能執行SQL語句:SQLSTATE [HY093]:無效的參數號:沒有定義的參數

這裏是我的代碼:

public function actionConfirmation 
{ 
    $model_person = new TempPerson(); 

    $model = $model_person->find('alias=:alias',array(':alias'=>$_GET['alias'])); 
    $connection=Yii::app()->db2; 
      $sql = "INSERT INTO users (username, password, ssn, surname 
        , firstname, email, city, country) 
        VALUES(:alias, :password, :ssn, :surname 
        , :firstname, :email, :city, :country)"; 
      $command=$connection->createCommand($sql); 
      $command->bindValue(":username", $model->alias); 
      $command->bindValue(":password", substr($model->ssn, -4,4)); 
      $command->bindValue(":ssn", $model->ssn); 
      $command->bindValue(":surname", $model->lastName); 
      $command->bindValue(":firstname", $model->firstName); 
      $command->bindValue(":email", $model->email); 
      $command->bindValue(":city", $model->placeOfBirth); 
      $command->bindValue(":country", $model->placeOfBirth); 
      $command->execute(); 
      $this->render('confirmation',array('model'=>$model)); 
} 

此構造下面的查詢(如在應用日誌中所見):

INSERT INTO users (username, password, ssn, surname, firstname, email 
        , city, country) 
VALUES(:alias, :password, :ssn, :surname, :firstname, :email, :city, :country); 

FYI $model->placeOfBirth應該是城市和縣的價值。這不是一個錯字(只是我必須做的一件愚蠢的事情)。

回答

73

只是提供一個答案 - 因爲這個錯誤是很常見的 - 這裏有幾個原因:

1):parameter名稱不匹配錯誤(錯字綁定)?這是發生在這裏的事情。他在SQL語句中有:alias,但是綁定了:username。因此,當試圖綁定param時,Yii/PDO在sql語句中找不到:username,這意味着它是「一個參數短」並引發錯誤。

2)完全忘記爲參數添加bindValue()。在Yii其他構造如$critera中這樣做更容易,其中您有一個數組或參數($criteria->params = array(':bind1'=>'test', ':bind2'=>'test))。

3)使用togetherjoins時與CDataProvider分頁和/或排序有奇怪的衝突。沒有特別的,簡單的方法來描述這一點,但是當在CDataProviders中使用複雜的查詢時,我遇到了一些奇怪的問題,因爲參數被丟棄並且發生這個錯誤。

解決Yii中這些問題的一個非常有用的方法是在配置文件中輸入enable parameter logging。在您的配置文件添加到您的db陣列:

'enableParamLogging'=>true, 

,並確保CWebLogRoute路線是建立在你的log部分。這將打印輸出的查詢和錯誤,以及它試圖綁定的所有參數。超級有用!

+4

好帖子。我發現在我的實例中,我在col列名之後有一個空格,並且足以引發錯誤。 – salonMonsters 2011-12-19 23:52:46

+4

我的問題是':參數'名稱中的變音符號... – testing 2012-08-31 13:37:12

+1

這裏有效的佔位符字符列表http://stackoverflow.com/questions/5809951/pdo-valid-characters-for-placeholders – maartenmachiels 2013-07-08 12:04:39

4

也許你正在嘗試在單引號內綁定一個參數,而不是讓它爲你完成工作。

比較:

Model::model()->findAll("t.description ilike '%:filter%'", array(':filter' => $filter)); 

有了:

Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%')); 
4

此錯誤的原因我上面沒有覆蓋的是當你與參數的動態數組處理,如果你取消設置任何參數,可以在傳遞它們之前,你需要重新索引。這個殘酷的部分是你的錯誤日誌不顯示索引,所以它看起來像一切都是正確的。例如:

SELECT id WHERE x = ?, y = ?, z = ? 

可能會產生的日誌:無效參數數:參數沒有被使用參數(「X」,「Y」,「Z」)

這看起來像它不應該被限定拋一個錯誤,但如果索引是這樣的:

0 => x, 1 => y, 4 => z 

它認爲最後的參數不確定,因爲它在尋找關鍵2.

+1

向您的答案添加一個簡單的print_r將顯示索引,並且可以使用array_values修復它,因爲它會重新索引從0開始的數組 – chifliiiii 2016-09-06 17:28:31

0

試圖做這樣的事情,當我得到這個錯誤:

$stmt = $pdo->prepare("select name from mytable where id = :id"); 
$stmt->execute([ 
    'id' => $id, 
    'unusedvar' => $foo, // This row causes the error. 
]); 

基本上,您不能將數組中未使用的參數傳遞給​​。在準備好的聲明中必須使用傳遞給​​的數組中的每個值。

這在docs還指定:小於指定

結合更多的值是不可能的;如果input_parameters中的鍵比PDO :: prepare()中指定的SQL更多,那麼語句將失敗併發出錯誤。

相關問題