Я пишу 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() в цикл, но это вызовет множество запросов, которые я хочу избежать любой ценой. Моя цель - это единственный запрос, независимо от того, что.
Я не думаю, что есть эффективность, но я никогда не сравнивал эти сравнения. –
Что касается «более простого кода, если выполняется в цикле»: по моему опыту в других (.Net) языках, пока запрос «подготовлен», различия в производительности незначительны между несколькими вариантами выполнения и «объемным» вставным запросом. Есть дополнительные преимущества для многозадачности, например, приходится много беспокоиться о том, что сам запрос становится длинным для вашего коннектора. – Uueerdo
... и под «query self» я имел в виду строку запроса. – Uueerdo