2016-05-11 6 views
0

PDOを使用してデータベースに挿入しようとすると、エラーが発生します。'SQLSTATE [HY093]:パラメータ番号が無効です'メッセージで「PDOException」が検出されました。

public function save($primaryKey = "") { 
     $validate = $this->rules(); 
     if ($validate === true) { 
      $properties = ''; 
      $values = ''; 
      $bindings = array(); 
      $update = ''; 
      foreach ($this as $property => $value){ 
       if ($property === "conn") { 
        continue; 
       } 
       $properties .= $property . ','; 
       $values .= ':' . $property . ','; 
       $update .= $property . ' = :' . $property . ','; 
       $bindings[':'.$property] = $value; 
      } 
      $sql_string = 'INSERT INTO ' . get_class($this) . ' (' . rtrim($properties, ',') . ') '; 
      $sql_string .= 'VALUES (' . rtrim($values, ',') . ') ON DUPLICATE KEY UPDATE ' . rtrim($update, ',') . ';'; 
      $result = $this->executeQuery(NULL, $sql_string, $bindings); 
      $this->buildObject($result); 
      if (!empty($primaryKey)) { 
       $this->$primaryKey = $this->conn->lastInsertId(); 
      } 
      return $result; 
     } else { 
      return $validate; 
     } 
    } 

public function executeQuery($object, $sql_string, $bindings = null) { 
     $stmt = $this->conn->prepare($sql_string); 
     if (!empty($bindings)) { 
      if (!$stmt->execute($bindings)) {return false;} 
     } else { 
      if (!$stmt->execute()) {return false;} 
     } 
     $result = (!empty($object) ? $stmt->fetchAll(PDO::FETCH_CLASS, $object) : $stmt->fetchAll()); 
     return (($stmt->rowCount() > 0) ? $result : false); 
    } 

save関数は、両方が正しいように見えるクエリ文字列とバインディングの両方を生成します。メッセージでキャッチされない例外「PDOException」「SQLSTATEを[HY093]:無効なパラメータ番号を」私は、私は問題はないが、コードでそれを実行しようとしたとき、私は致命的なエラーを取得するワークベンチにクエリを置くたび

query = INSERT INTO am_administrator (firstName,lastName,username,password,email,isSuperUser,dateCreated,dateLastModified) VALUES (:firstName,:lastName,:username,:password,:email,:isSuperUser,:dateCreated,:dateLastModified) ON DUPLICATE KEY UPDATE firstName = :firstName,lastName = :lastName,username = :username,password = :password,email = :email,isSuperUser = :isSuperUser,dateCreated = :dateCreated,dateLastModified = :dateLastModified; 

bindings = array(8) { 
[":firstName"]=> string(5) "First" 
[":lastName"]=> string(4) "Last" 
[":username"]=> string(7) "cova-fl" 
[":password"]=> string(8) "password" 
[":email"]=> string(16) "[email protected]" 
[":isSuperUser"]=> int(1) "1" 
[":dateCreated"]=> string(19) "2016-05-11 02:40:15" 
[":dateLastModified"]=> string(19) "2016-05-11 02:40:15" 
} 

bindingsの数がバインディングのキーとnummbersと一致するので、私は混乱します。誰でもこの問題について私に啓発できますか?

+0

注:これは、 'よりも連結して取り除くために(「」、$値)[]'、その配列に追加し、最終的には、 '破=' $値を行うには通常、多くの方が良いでしょう余分な '、'。 – tadman

+0

ある時点で、[Doctrine](http://www.doctrine-project.org/)や[Propel](http://propelorm.org/)のようなORMを使用して、開発フレームワーク](http://codegeekz.com/best-php-frameworks-for-developers/)を使用してください。 [Laravel](http://laravel.com/)は特に使いやすいもので、必要なものをすぐに購入できます。 – tadman

+0

@tadman Noted、その変更を行います。私の主な問題について何か知っていますか?私はORMが制限されているため制限されています。だから私は良いまたは楽しいではない小さなものを構築することがあります... –

答えて

1

これは、文章で各バインディングを2回宣言したためと思われます。 :firstnameは、句とON DUPLICATE KEY UPDATE句に表示されます。

あなただけ$stmt->executeに8つのバインディングを渡すが、PDOは16

を探しているあなたは、あなたに、このような例としてクエリを与えるON DUPLICATE KEY UPDATE句でわずかに異なるそれらを命名試みることができます

INSERT INTO am_administrator (firstName,lastName,username,password,email,isSuperUser,dateCreated,dateLastModified) VALUES (:firstName,:lastName,:username,:password,:email,:isSuperUser,:dateCreated,:dateLastModified) ON DUPLICATE KEY UPDATE firstName = :update_firstName,lastName = :update_lastName,username = :update_username,password = :update_password,email = :update_email,isSuperUser = :update_isSuperUser,dateCreated = :update_dateCreated,dateLastModified = :update_dateLastModified;

+0

ありがとうございました。私はバインディング値がクエリ文字列のバインディングパラメータのすべてのインスタンスで共有できないことを知りませんでした。 –

+0

[VALUES](http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values)を使用するだけではいかがですか? INSERT INTOテーブル(firstName、lastName)VALUES(:firstName、:lastName)重複キー更新でfirstName = VALUES(firstName)、lastName = VALUES(lastName) '?そうすれば、多くのプレースホルダーを持つ必要はありません。 – Mikey

関連する問題