Intereting Posts
Замените повторяющиеся значения в массиве новыми случайно генерируемыми значениями Как найти день недели с даты с помощью PHP? Метод заполнения в Laravel не работает? Функция PHP использует переменную извне Поиск номеров телефонов в базе данных, игнорирующих специальные символы Как вызвать скрипт php с использованием элементов формы html вместо командной строки? Рандомизация – и запоминание того, что вопросы рандомизации – множественного выбора в php Встроенные формы Несколько полей – Symfony2 Несколько полей JQuery PHPUnit загружает все классы одновременно. Вызывает PHP Неустранимая ошибка: не удается переопределить класс Прогресс загрузки cURL в PHP Stripe – ошибка PHP – Stripe больше не поддерживает запросы API, сделанные с помощью TLS 1.0 406 Неприемлемая ошибка на реальном сервере – JSON Можно ли изменить default_socket_timeout из моего php-кода? php – добавить переменную от двух часов до даты Синтаксис для инструкции if / else, если вставка была успешной в подготовленном заявлении PDO

Вставка PDO при обновлении повторяющегося ключа

После публикации этого вопроса MySQL update или insert или die query, я изменил использование PDO, но у меня возникли проблемы с использованием дублирующей фразы обновления ключа.

Вот пример данных моего массива

array(114) { ["fname"]=> string(6) "Bryana" ["lname"]=> string(6) "Greene" ["m080"]=> string(1) "c" ["t080"]=> string(1) "-" ["w080"]=> string(1) "-" ["r080"]=> ["notes"]=> string(4) "yoyo"} 

На самом деле есть 113 полей, но я не хотел терять пространство, показывая им все здесь. В настоящее время я пытаюсь ввести INSERT / UPDATE в мою базу данных с помощью следующего кода

 try { $dbh = new PDO('login info here'); $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); $stmt = $dbh->prepare( 'INSERT INTO fhours ('.implode(",", array_keys($faculty)).')'. ' VALUES (:'.implode(",:", array_keys($faculty)).')'. ' ON DUPLICATE KEY UPDATE :fieldlist'); $stmt->bindParam(':field_list', $field_list); foreach($faculty as $key=>$val){ $stmt->bindParam(':'.$key, $val); $fields[] = sprintf("%s = :%s", $key, $key); } $field_list = join(',', $fields); //echo $stmt->debugDumpParams(); $stmt->execute(); } catch(PDOException $e){ echo $e->getMessage(); exit(); } 

Я получаю номер параметра Invalid: параметр не был указан в сообщении об ошибке. Я уверен, что мои проблемы заключаются в ON DUPLICATE KEY UPDATE :fieldlist'); но я сделал так много разных попыток, и никто из них не работал. Должен ли я вообще использовать ON DUPLICATE KEY UPDATE ?

Кроме того, я новичок в синтаксисе: и ::, означает :name означает, что это именованная переменная типа $name и делает PDOStatement::bindValue вроде как PDOStatement->bindValue ?

редактировать

В ответ на первые два комментария ниже я обновил код таким образом (но все же безрезультатно, debugDumpParams говорит, что у меня нет параметров). Кроме того, зачем создавать параметры $array_of_parameters когда он становится тем же самым массивом, что и $faculty ?

  //grab form data $faculty = $_POST; $fname = $_POST['fname']; $lname = $_POST['lname']; //delete the submit button from array unset($faculty['submit']); $array_of_parameters = array(); foreach($faculty as $key=>$val){ $array_of_parameters[$key] = $val; $fields[] = sprintf("%s=?", $key); } $field_list = join(',', $fields); try { $dbh = new PDO('mysql:host=localhost;dbname=kiosk', 'kiosk', 'K10$k'); $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); $update = 'UPDATE fhours SET '.$field_list. 'WHERE fname="'.$fname.'" AND '. 'lname="'.$lname.'"'; $stmt = $dbh->prepare($update); //echo $stmt->debugDumpParams(); $stmt->execute(array($array_of_parameters)); if($stmt->rowCount() == 0){ $insert = 'INSERT INTO fhours ('.implode(",", array_keys($faculty)).')'. ' VALUES (:'.implode(",:", array_keys($faculty)).')'; $stmt = $dbh->prepare($insert); $stmt->execute(array($array_of_parameters)); } } catch(PDOException $e){ echo $e->getMessage(); exit(); } $dbh=null; с  //grab form data $faculty = $_POST; $fname = $_POST['fname']; $lname = $_POST['lname']; //delete the submit button from array unset($faculty['submit']); $array_of_parameters = array(); foreach($faculty as $key=>$val){ $array_of_parameters[$key] = $val; $fields[] = sprintf("%s=?", $key); } $field_list = join(',', $fields); try { $dbh = new PDO('mysql:host=localhost;dbname=kiosk', 'kiosk', 'K10$k'); $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); $update = 'UPDATE fhours SET '.$field_list. 'WHERE fname="'.$fname.'" AND '. 'lname="'.$lname.'"'; $stmt = $dbh->prepare($update); //echo $stmt->debugDumpParams(); $stmt->execute(array($array_of_parameters)); if($stmt->rowCount() == 0){ $insert = 'INSERT INTO fhours ('.implode(",", array_keys($faculty)).')'. ' VALUES (:'.implode(",:", array_keys($faculty)).')'; $stmt = $dbh->prepare($insert); $stmt->execute(array($array_of_parameters)); } } catch(PDOException $e){ echo $e->getMessage(); exit(); } $dbh=null; 

То, что вы пытались сделать, – это динамически построить строку SQL, которая будет параметризоваться. Параметрами :paramname как ожидается, являются одиночные значения, сопоставленные значениям столбцов, параметрам предложения и т. Д. Вместо этого вы использовали $fields[] = sprintf("%s = :%s", $key, $key); для создания строки полей :paramname , чтобы подключиться к запросу. Это просто не будет работать в параметризованной инструкции.

Вместо того, чтобы делать ON DUPLICATE KEY UPDATE :fieldlist , вы должны собрать всю строку sql перед передачей ее в prepare() .

Затем вместо использования bindParam() для привязки каждого отдельно, вы можете использовать альтернативный синтаксис для execute() для передачи в массив ожидаемых параметрических значений. Они должны быть в правильном порядке или иметь ключи массива с теми же именами, что и параметры :param в вашем SQL. Дополнительную информацию и примеры см. В документах.

 $array_of_parameters = array(); foreach($faculty as $key=>$val){ $array_of_parameters[$key] = $val); } $stmt->execute($array_of_parameters); 

РЕДАКТИРОВАТЬ Для правильного использования параметров в UPDATE выполните следующие действия:

 // Create your $field_list before attempting to create the SQL statement $field_list = join(',', $fields); $update = 'UPDATE fhours SET '.$field_list. 'WHERE fname=:fname AND lname=:lname'; // Here, echo out $update to make sure it looks correct // Then add the fname and lname parameters onto your array of params $array_of_parameters[] = $_POST['fname']; $array_of_parameters[] = $_POST['lname']; // Now that your parameters array includes all the faculty in the correct order and the fname & lname, // you can execute it. $stmt->prepare($update); $stmt->execute($array_of_parameters); 

Имя с двоеточием – это не что иное, как именованный заполнитель. Когда вы переходите на привязку своих параметров, вы просто привязываете свой placeholder к некоторой произвольной ценности.

ON DUPLICATE KEY UPDATE не очень дружелюбен к нескольким СУБД, но если вы подключены к совместимой базе данных, он должен работать (поскольку я не верю, что PDO заблокирует все это, но я могу ошибаться). Я бы не использовал его только ради мобильности. Вы можете проверить, как вы привязываете свои полевые списки, хотя bindparam должен выполнять только один параметр, а это коды, которые не должны указываться как значения (которые будут связаны с параметром bind).

Я проектирую upserts, выполняя максимум два запроса: Update, затем Insert. Сначала я обновлю и проверю, больше ли число обновленных строк. Если затронутые строки равны 0, запустите Insert.

Просто пустой комментарий, 113 полей – это много полей, вы можете пострадать от некоторой производительности таблицы, если не будете осторожны