Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

PHP/SQL Insert Error saat menggunakan Named Placeholder

$userData . Anda harus memiliki tempat penampung yang sama persis dengan pernyataan Anda, tidak lebih dan tidak kurang. Lihat PDOStatement::execute dokumentasi , bagian yang mengatakan "Anda tidak dapat mengikat nilai lebih dari yang ditentukan".

Anda perlu menyiapkan argumen Anda untuk execute() untuk mencocokkan ikatan Anda dengan tepat. Ini mudah dengan array_intersect_key() jika Anda mengatur array Anda dengan benar. Saya biasanya membungkus ini dalam fungsi yang juga akan menangani awalan, seperti di bawah ini:

// Adds a prefix to a name for a named bind placeholder
function prefix($name) {
    return ':'.$name;
}

// like 'prefix()', but for array keys
function prefix_keys($assoc) {
    // prefix STRING keys
    // Numeric keys not included
    $newassoc = array();
    foreach ($assoc as $k=>$v) {
        if (is_string($k)) {
            $newassoc[prefix($k)] = $v;
        }
    }
    return $newassoc;
}

// given a map of datakeyname=>columnname, and a table name, returns an
// sql insert string with named bind placeholder parameters.
function makeInsertStmt($tablename, $namemap) {
    $binds = array_map('prefix', array_keys($namemap));
    return 'INSERT INTO '.$tablename.' ('.implode(',',$namemap).') VALUES ('
    .implode(',',$binds).')';
}

// returns an array formatted for an `execute()`
function makeBindData($data, $namemap) {
    // $data assoc array, $namemap name->column mapping
    return prefix_keys(array_intersect_key($data, $namemap));
}

// example to demonstrate how these pieces fit together
function RunTestInsert(PDO $pdo, $userData) {
    $tablename = 'UserDetails';
    // map "key in $userData" => "column name"
    // do not include ':' prefix in $userData
    $namemap = array(
      'firstName'       => "FirstName",
      'lastName'        => "LastName",
      'address'         => "Address",
      'city'            => "City",
      'county'          => "County",
      'postCode'        => "PostCode",
      'phone'           => "Phone",
      'mobile'          => "Mobile",
      'sex'             => "Sex",
      'DOB'             => "DOB",
      'fundraisingAim'  => "FundraisingAim",
      'weeksAim'        => "WeeksAim",
      'lengthsAim'      => "LengthsAim",
      'hearAbout'       => "HearAboutID",
      'motivation'      => "MotivationID",
      'welcomePackPref' => "WelcomePackID",
      'contactPref'     => "ContactPrefID",
      'title'           => "TitleID",
    );
    $sql = makeInsertStmt($tablename, $namemap);
    $binddata = makeBindData($userData, $namemap);

    $pstmt = $pdo->prepare($sql);
    $pstmt->execute($binddata);
}

Manfaat dari abstraksi seperti ini adalah Anda tidak perlu khawatir tentang parameter bind itu sendiri.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kinerja MySQL:Mengidentifikasi Pertanyaan Panjang

  2. Bagaimana saya bisa menggunakan now() di Doctrine 2 DQL?

  3. Izin Pengguna MySQL

  4. GABUNG dengan GROUP BY dalam DB yang Dinormalisasi tentang Sumber Daya, Topik &Bab

  5. Mempercepat (Bulk) Masukkan ke MySQL dengan Python