Как проверить наличие дубликата записи перед вставкой с помощью wpdb

24 июн. 2014 г., 11:08:23
Просмотры: 17.9K
Голосов: 11

Я вставляю строку в пользовательскую таблицу в базе данных WordPress. Вот мой код:

$wpdb->insert( 'wp_pl_my_parts', 
                    array( 
                    'user_ID' => $user_ID, 
                    'PL_part_ID' => $PL_part_ID, 
                    'part_save_date' => $part_save_date ), array( '%d', '%d', '%s' ) );

Как мне убедиться, что я не вставляю дублирующую запись? То есть, я не хочу вставлять запись, если user_ID и PL_part_ID совпадают с уже существующей записью?

Дата не имеет значения и не должна проверяться.

0
Все ответы на вопрос 4
1
10

Допустим, первичный ключ таблицы — это my_part_ID. Тогда мы проверим, существует ли какое-либо значение первичного ключа для комбинации user_ID и PL_part_ID, следующим образом:

$my_part_ID = $wpdb->get_var(
                $wpdb->prepare(
                    "SELECT my_part_ID FROM " . $wpdb->prefix . "pl_my_parts
                    WHERE user_ID = %d AND PL_part_ID = %d LIMIT 1",
                    $user_ID, $PL_part_ID
                )
            );

if ( $my_part_ID > 0 )
    // существует
else
    // не существует
24 июн. 2014 г. 13:35:22
Комментарии

Если вы проверяете полученные $rows, вам нужно использовать count($rows), чтобы условие if работало правильно - то есть if ( count($rows) > 0 )

pbaranski pbaranski
25 июл. 2018 г. 10:36:43
8

Я обнаружил, что лучший способ проверить существование записи с помощью WPDB — это сначала использовать функцию обновления WPDB. Пример этого может выглядеть так:

    if(!$wpdb->update($wpdb->prefix.'table_name',$data,array('id'=>$dbRowId),array('%s'),array('%d'))){
        $wpdb->insert($wpdb->prefix.'table_name',$data,array('%s'));
        return $wpdb->insert_id;
    }else{
        return $dbRowId;
    }

Это немного больше, чем вам может хотеться с точки зрения общей функции, но если вы настроите её как вызываемый метод в модели или классе базы данных вашего плагина или темы, вы сможете поручить ей обработку функциональности WPDB.

24 июн. 2014 г. 11:31:23
Комментарии

Звучит интересно, если посмотреть на мой исходный код, как это будет работать. Я думаю, что использую $dbRowId, если я правильно понял написанное вами, это my_part_ID. Там, где вы указали database_name, разве не должно быть имени таблицы?

M1 Creative Developer M1 Creative Developer
24 июн. 2014 г. 11:59:52

@Caleuanhopkins при вставке записи, как можно получить $dbRowId или, возможно, значение первичного ключа в данном случае?

Chittaranjan Chittaranjan
24 июн. 2014 г. 13:19:38

@Chittaranjan переменная $dbRowId — это просто пример переменной; чтобы получить идентификатор вставленной строки, $wpdb->insert_id; вернет идентификатор строки, только что вставленной в базу данных.

Caleuanhopkins Caleuanhopkins
24 июн. 2014 г. 18:11:08

@M1CreativeDeveloper Да, я также обновил код и изменил название базы данных на имя таблицы. Извините за путаницу.

Caleuanhopkins Caleuanhopkins
24 июн. 2014 г. 18:19:41

@Caleuanhopkins эта переменная абсолютно корректна. В вопросе сказано before inserting, так как же у вас может быть $dbRowId в запросе на обновление?

Chittaranjan Chittaranjan
24 июн. 2014 г. 23:33:31

@Chittaranjan $dbRowId может быть null, если он недоступен. Его цель - проверить, существует ли строка, и если нет, вставить новую. $dbRowId можно заменить на $PL_part_ID, это просто пример кода, а не готовое решение для копирования.

Caleuanhopkins Caleuanhopkins
25 июн. 2014 г. 18:38:44

Да, это просто пример кода. Но суть, которую я пытаюсь донести, в том, что $dbRowId передается как условие WHERE в запросе UPDATE. Так что если оно null, то будет ли вообще обновлена какая-либо запись? Другими словами, если оно null, значит записи в базе данных нет, тогда какой смысл выполнять запрос на обновление?

Chittaranjan Chittaranjan
25 июн. 2014 г. 23:21:18

@Chittaranjan это универсальный код управления WPDB, который при выполнении, если в коде есть переменная, которую можно использовать для проверки существования строки в БД, проверит эту строку. Если такой переменной нет или не найдено строки на основе этой переменной, он добавит новую строку в БД. Ваш пример помогает проверить строку, но не добавляет новую строку, если она не найдена. $dbRowId в примере может быть null, или может быть ID строки для проверки, это также может быть другая переменная, хранящаяся в строке, например $PL_part_ID, используемая для идентификации того, что нужно проверить, чтобы определить, существует ли строка уже.

Caleuanhopkins Caleuanhopkins
26 июн. 2014 г. 11:37:23
Показать остальные 3 комментариев
7

Просто создайте таблицу в базе данных с индексом (или индексами) UNIQUE, чтобы предотвратить дублирование. Для начала ознакомьтесь с MySQL: Синтаксис CREATE INDEX. Что касается специфики WordPress, изучите Codex: Создание таблиц с помощью плагинов - Создание таблиц базы данных. Пример кода ниже взят оттуда:

global $wpdb;
$sql = "CREATE TABLE $table_name (
  id mediumint(9) NOT NULL AUTO_INCREMENT,
  time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
  name tinytext NOT NULL,
  text text NOT NULL,
  url VARCHAR(55) DEFAULT '' NOT NULL,
  UNIQUE KEY id (id)
);";

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );

Суть этого ответа заключается в том, чтобы предотвратить проблему, с которой столкнулся автор вопроса, заранее. То есть путем проектирования, планирования и настройки системы таким образом, чтобы проблема вообще не могла возникнуть.

24 июн. 2014 г. 13:48:40
Комментарии

Пользователь запрашивает запись, а не таблицу, И этот ответ на самом деле не совсем подходит на вопрос, заданный автором.

Mike Kormendy Mike Kormendy
21 февр. 2017 г. 01:24:51

@MikeKormendy Ну, верно, автор спрашивал про запись. Мой ответ всё ещё валиден, потому что если вы создаёте таблицу с установкой ID или некоторых ID как уникальных, то это гарантирует, что они будут уникальными. Что, в свою очередь, решает проблему автора, а именно предотвращение записей с дублирующимися индексами. Так что ваша оценка здесь не совсем корректна.

Nicolai Grossherr Nicolai Grossherr
21 февр. 2017 г. 13:44:39

Моя оценка такова, что ваш ответ расплывчат и недостаточно конкретен, чтобы быть наиболее подходящим ответом. 1. Автор никогда не просил уникальный индекс, несмотря на то, что это может косвенно решить вопрос. 2. Автор спрашивал про два уникальных поля, ваш ответ в деталях не затрагивает этот вопрос напрямую. Не стесняйтесь изменить свой ответ, чтобы он точно и конкретно отвечал на вопрос.

Mike Kormendy Mike Kormendy
21 февр. 2017 г. 18:32:30

Автору вопроса также придется рефакторить свой код, чтобы учитывать уникальные записи по индексу, а не проверять сами уникальные значения. Вы не предоставили этот код или ссылки на ресурсы для выполнения данной задачи.

Mike Kormendy Mike Kormendy
21 февр. 2017 г. 18:39:14

@MikeKormendy Метод insert в $wpdb учитывает уникальность. Кроме того, ответы не обязаны давать полные решения, но должны помогать в решении проблемы — мой ответ соответствует этому критерию. Я не против, если вы не согласны, но тогда вам не стоит возражать, если я не согласен с вами.

Nicolai Grossherr Nicolai Grossherr
21 февр. 2017 г. 20:04:27

В этом и прелесть публичных Q&A на форумах. Моя оценка и минус остаются в силе, пока ваш ответ не будет улучшен и станет более конкретным в отношении вопроса автора. Точка.

Mike Kormendy Mike Kormendy
21 февр. 2017 г. 21:07:01

@MikeKormendy Как я уже сказал, я просто не согласен с вашей оценкой, без лишних сложностей. Я даже проголосовал за ваш оригинальный комментарий. Кроме того, я отредактировал свой ответ, чтобы пояснить свою цель.

Nicolai Grossherr Nicolai Grossherr
21 февр. 2017 г. 21:38:25
Показать остальные 2 комментариев
1
global $wpdb;
$table_user = $wpdb->prefix . 'user';
$PL_part_ID= $_POST['PL_part_ID'];
// сначала проверяем существование данных с помощью SELECT запроса
$datum = $wpdb->get_results("SELECT * FROM $table_user WHERE PL_part_ID= '".$PL_part_ID."'");
 if($wpdb->num_rows > 0) {
 echo "результат существует";
 }
// если не существует в базе данных, тогда вставляем
else{
$result = $wpdb->insert( 
$table_token, 
array( 
'Firstname' => $_POST["value1"], // Имя
'Surname' => $_POST["value2"], // Фамилия
'Month' => $_POST["value3"], // Месяц
'Day' => $_POST["value4"], // День
'Email Address' => $_POST["value5"] // Адрес электронной почты
)
);
}
23 сент. 2016 г. 14:18:19
Комментарии

Пожалуйста, отдавайте предпочтение методу $wpdb->prepare().

bravokeyl bravokeyl
23 сент. 2016 г. 14:41:45