Cómo verificar registros duplicados antes de insertar usando wpdb en WordPress
Estoy insertando una fila en una tabla personalizada de la base de datos de WordPress. Este es el código:
$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' ) );
¿Cómo puedo asegurarme de no insertar una entrada duplicada? Es decir, no quiero que inserte si el user_ID y el PL_part_ID son iguales a un registro existente?
La fecha no importa y no debe ser verificada.

Digamos que la clave primaria de la tabla es my_part_ID
. Entonces verificaremos si existe algún valor de clave primaria para la combinación de user_ID
y PL_part_ID
de la siguiente manera:
$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 )
// existe
else
// no existe

He encontrado que la mejor manera de verificar si un registro existe o no con WPDB es comprobarlo primero usando la función de actualización de WPDB. Un ejemplo de esto podría ser:
if(!$wpdb->update($wpdb->prefix.'nombre_tabla',$data,array('id'=>$dbRowId),array('%s'),array('%d'))){
$wpdb->insert($wpdb->prefix.'nombre_tabla',$data,array('%s'));
return $wpdb->insert_id;
}else{
return $dbRowId;
}
Es un poco más grande de lo que podrías querer en términos de una función general, pero si lo configuras como un método invocable en un modelo o clase de base de datos en tu plugin o tema, puedes hacer que maneje la funcionalidad de WPDB.

Eso suena interesante, mirando mi código original, ¿cómo funcionaría eso? Creo que estoy usando $dbRowId, si entiendo lo que has escrito, es my_part_ID. Donde has puesto database_name, ¿no debería ser el nombre de la tabla?

@Caleuanhopkins al insertar el registro, ¿cómo obtendrá alguien $dbRowId
o posiblemente el valor de la clave primaria en este caso?

@Chittaranjan la variable $dbRowId es solo un ejemplo de variable, para obtener el id de una fila insertada, $wpdb->insert_id;
devolverá el id de la fila recién insertada en la base de datos

@M1CreativeDeveloper Sí, también he actualizado el código y cambié el nombre de la base de datos por el nombre de la tabla. Disculpa la confusión.

@Caleuanhopkins esa variable está perfectamente bien. La pregunta dice before inserting
(antes de insertar), así que ¿cómo puedes tener $dbRowId
en la consulta de actualización?

@Chittaranjan $dbRowId
podría ser nulo si no está disponible. El objetivo es verificar si existe una fila, y si no, insertar una nueva fila. $dbRowId
podría cambiarse por $PL_part_ID
, es solo un código de ejemplo, no es una solución para copiar y pegar.

Sí, es solo un código de ejemplo. Pero el punto al que intento referirme aquí es que $dbRowId
se pasa como condición WHERE en la consulta de actualización. Entonces, si es nulo, ¿actualizará algún registro? En otras palabras, si es nulo, entonces no hay ningún registro en la base de datos, entonces ¿cuál es el punto de ejecutar una consulta de actualización?

@Chittaranjan es un código universal de administración de WPDB que, cuando se ejecuta, si el código tiene una variable que puede usar para verificar si una fila ya existe en la BD, verificará esa fila. Si no tiene esa variable o no hay una fila que se pueda encontrar basada en esa variable, inserta una nueva fila en la BD. Tu ejemplo ayuda a verificar una fila, pero no inserta una nueva fila si no se encuentra ninguna. $dbRowId
en el ejemplo puede ser nulo, o puede ser un ID o una fila para verificar, también podría ser una variable diferente almacenada en una fila, como $PL_part_ID
utilizado para identificar qué verificar para determinar si una fila ya existe.

Solo crea tu tabla de base de datos con un índice (o índices) UNIQUE
para evitar duplicados, consulta MySQL: Sintaxis de CREATE INDEX para comenzar. Para los aspectos específicos de WordPress, echa un vistazo a Codex: Creación de tablas con Plugins - Crear tablas de base de datos. El siguiente código de ejemplo está tomado de allí:
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 );
La premisa de esta respuesta es prevenir el problema que está experimentando el OP desde el principio. Es decir, diseñando, planificando y configurándolo de manera que el problema no pueda ocurrir en primer lugar.

El usuario solicita un registro, no una tabla Y esta respuesta realmente no es la adecuada para la pregunta hecha por el OP.

@MikeKormendy Bueno, es cierto, el OP preguntó por el registro. Mi respuesta sigue siendo válida, porque si creas la tabla configurando el ID o algunos IDs como únicos, entonces se asegura que esos sean únicos. Lo cual ergo lleva a resolver el problema del OP, que es prevenir entradas con índices duplicados. Así que tu evaluación aquí no es completamente correcta.

mi evaluación es que tu respuesta es vaga y no lo suficientemente específica para ser la respuesta más apropiada. 1. el OP nunca preguntó por un índice único independientemente de que ese posible resultado remoto resuelva la pregunta. 2. el OP estaba preguntando por dos campos únicos, tu respuesta en especificidad, no aborda esa pregunta exactamente. Siéntete libre de cambiar tu respuesta a la pregunta directamente, de manera específica.

El OP también tendría que refactorizar su código para ajustar las entradas únicas por índice en lugar de verificar los valores únicos en sí mismos. No has proporcionado ese código ni enlaces de recursos para hacerlo.

@MikeKormendy El método insert
de $wpdb
respeta la unicidad. Además, las respuestas no tienen que dar soluciones completas, pero deben ser útiles para resolver un problema; mi respuesta cumple con eso. No me importa si no estás de acuerdo, pero entonces no debería importarte si yo no estoy de acuerdo contigo.

Eso es lo bueno de los foros públicos de preguntas y respuestas. Mi evaluación y voto negativo siguen en pie hasta que tu respuesta mejore para ser más específica a la pregunta del OP. Caso cerrado.

global $wpdb;
$table_user = $wpdb->prefix . 'user';
$PL_part_ID= $_POST['PL_part_ID'];
// primero verificar si los datos existen con una consulta SELECT
$datum = $wpdb->get_results("SELECT * FROM $table_user WHERE PL_part_ID= '".$PL_part_ID."'");
if($wpdb->num_rows > 0) {
echo "el resultado existe";
}
// si no existe en la base de datos, entonces insertarlo
else{
$result = $wpdb->insert(
$table_token,
array(
'Nombre' => $_POST["value1"],
'Apellido' => $_POST["value2"],
'Mes' => $_POST["value3"],
'Día' => $_POST["value4"],
'Correo Electrónico' => $_POST["value5"]
)
);
}
