Cómo verificar registros duplicados antes de insertar usando wpdb en WordPress

24 jun 2014, 11:08:23
Vistas: 17.9K
Votos: 11

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.

0
Todas las respuestas a la pregunta 4
1
10

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
24 jun 2014 13:35:22
Comentarios

Si estás verificando mediante $rows recibido, necesitas usar count($rows) para que el if funcione correctamente - entonces sería if ( count($rows) > 0 )

pbaranski pbaranski
25 jul 2018 10:36:43
8

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.

24 jun 2014 11:31:23
Comentarios

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?

M1 Creative Developer M1 Creative Developer
24 jun 2014 11:59:52

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

Chittaranjan Chittaranjan
24 jun 2014 13:19:38

@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

Caleuanhopkins Caleuanhopkins
24 jun 2014 18:11:08

@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 Caleuanhopkins
24 jun 2014 18:19:41

@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 Chittaranjan
24 jun 2014 23:33:31

@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.

Caleuanhopkins Caleuanhopkins
25 jun 2014 18:38:44

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 Chittaranjan
25 jun 2014 23:21:18

@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.

Caleuanhopkins Caleuanhopkins
26 jun 2014 11:37:23
Mostrar los 3 comentarios restantes
7

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.

24 jun 2014 13:48:40
Comentarios

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

Mike Kormendy Mike Kormendy
21 feb 2017 01:24:51

@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.

Nicolai Grossherr Nicolai Grossherr
21 feb 2017 13:44:39

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.

Mike Kormendy Mike Kormendy
21 feb 2017 18:32:30

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.

Mike Kormendy Mike Kormendy
21 feb 2017 18:39:14

@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.

Nicolai Grossherr Nicolai Grossherr
21 feb 2017 20:04:27

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.

Mike Kormendy Mike Kormendy
21 feb 2017 21:07:01

@MikeKormendy Como dije, simplemente no estoy de acuerdo con tu evaluación, sencillo y claro. De hecho, incluso voté positivamente tu comentario original. Además, edité mi respuesta para explicar mi objetivo.

Nicolai Grossherr Nicolai Grossherr
21 feb 2017 21:38:25
Mostrar los 2 comentarios restantes
1
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"]
)
);
}
23 sept 2016 14:18:19
Comentarios

Por favor, prefiere el método $wpdb->prepare().

bravokeyl bravokeyl
23 sept 2016 14:41:45