2015-05-04 1 views
0

Я пишу PHP, чтобы принять массив чисел и имен в POST и вставить их в таблицу MySQL (названный Contacts_table) Вот версия, которая работает отлично без каких-либо ошибок:Вставка нескольких строк (один запрос) в MySQL в PHP: Подготовка-Выполнение против Prepare-Bind-Execute

<?php 

    // Includes 
    require_once 'Admin/Connector.php'; 

    // Test if payload exists 
    if($_POST){ 

    // Read payload into arrays 
     $ar = 0; 
     foreach($_POST as $entry){ 
      $namenum = explode(',', $entry); 
      $names[$ar] = $namenum[1]; 
      $numbers[$ar] = $namenum[0]; 
      $ar += 1; 
     } 
     $namenum = NULL; 

    // Build SQL query 
     $sql = 'INSERT INTO Contact_table (NAME, PHONE) VALUES '; 
     $insertQuery = array(); 
     $insertData = array(); 
     $n = 0; 
     foreach ($numbers as $num) { 
     $insertQuery[] = '(?, ?)'; 
     $insertData[] = $names[$n]; 
     $insertData[] = $num; 
     $n++; 
     } 
     $sql .= implode(', ', $insertQuery); 
     $sql .= ' ON DUPLICATE KEY UPDATE name = COALESCE(VALUES(name), name);'; 
     $n = NULL; 
     $num = NULL; 

    // Connect to MySQL database 
     $connect = dbconn(PROJHOST,PROJDB,PROJDBUSER,PROJDBPWD); 

    // Execute SQL query 
     $query = $connect->prepare($sql); 
     $query->execute($insertData); 
     $insertQuery = NULL; 
     $insertData = NULL; 
     $sql = NULL; 
     $query = NULL; 

    // Close connection to MySQL database 
     $connect = NULL; 

    } 

?> 

Однако, как вы можете видеть, я не использую в bindParam() функции здесь и просто кормил значение непосредственно на execute() functi на. Многие рекомендовали использовать вместо этого значение bindParam() для повышения производительности сервера. Это правда, или мне лучше работать с этой программой? Я попытался писать и запустить версию выше кода с использованием bindParam:

<?php 

    // Includes 
    require_once 'Admin/Connector.php'; 

    // Test if payload exists 
    if($_POST){ 

    // Read payload into arrays 
     $ar = 0; 
     foreach($_POST as $entry){ 
      $namenum = explode(',', $entry); 
      $names[$ar] = $namenum[1]; 
      $numbers[$ar] = $namenum[0]; 
      $ar += 1; 
     } 
     $namenum = NULL; 

    // Build SQL query 
     $sql = 'INSERT INTO Contact_table (NAME, PHONE) VALUES '; 
     $insertQuery = array(); 
     $insertData = array(); 
     $n = 0; 
     foreach ($numbers as $num) { 
     $insertQuery[] = '(?, ?)'; 
     $insertData[] = $names[$n]; 
     $insertData[] = $num; 
     $n++; 
     } 
     $sql .= implode(', ', $insertQuery); 
     $sql .= ' ON DUPLICATE KEY UPDATE name = COALESCE(VALUES(name), name);'; 
     $n = NULL; 
     $num = NULL; 

    // Connect to MySQL database 
     $connect = dbconn(PROJHOST,PROJDB,PROJDBUSER,PROJDBPWD); 

    // Prepare SQL query 
     $query = $connect->prepare($sql); 

    // Bind variables 
     foreach($insertData as $key => &$ins) { 
      $connect->bindParam($key+1,$ins); 
     } 

    // Execute SQL query 
     $query->execute(); 
     $insertQuery = NULL; 
     $insertData = NULL; 
     $sql = NULL; 
     $query = NULL; 
     $key = NULL; 
     $ins = NULL; 

    // Close connection to MySQL database 
     $connect = NULL; 

    } 

?> 

Но этот код не запускается и возвращает фатальную ошибку - Призыв к неопределенному методу PDO :: bindParam(). Что я здесь делаю неправильно? Я понимаю, что можно написать гораздо более простой код, если я включу execute() в цикл, но это вызовет множество запросов, которые я хочу избежать любой ценой. Моя цель - это единственный запрос, независимо от того, что.

+0

Я не думаю, что есть эффективность, но я никогда не сравнивал эти сравнения. –

+1

Что касается «более простого кода, если выполняется в цикле»: по моему опыту в других (.Net) языках, пока запрос «подготовлен», различия в производительности незначительны между несколькими вариантами выполнения и «объемным» вставным запросом. Есть дополнительные преимущества для многозадачности, например, приходится много беспокоиться о том, что сам запрос становится длинным для вашего коннектора. – Uueerdo

+0

... и под «query self» я имел в виду строку запроса. – Uueerdo

ответ

1

Вы не можете $connect->bindParam($key+1,$ins);. Поскольку объект PDO не имеет такого метода. Только PDOStatement имеет. Вот почему вы получили сообщение об ошибке.

Вы должны:

$query->bindValue($key+1,$ins); 

И вы должны использовать bindValue, потому что если нет, то все ваши вставленные значения получат одинаковое значение (последний из $ ины перед вызовом execute).