¿Cómo usar wpdb->prepare con MySQL UPDATE?

19 oct 2011, 20:17:30
Vistas: 39K
Votos: 0

Estoy tratando de establecer una fecha y hora de 'eliminado' en una consulta de plugin pero no estoy seguro de cómo usar UPDATE SET con $wpdb->prepare.

Aquí está mi consulta:

$cur_date = date('Y-m-d G:i:s');        
$rows_affected = $wpdb->query(
    $wpdb->prepare("
        UPDATE $table
        SET ( removed, post_id, user_id, status )
        VALUES ( %s, %d, %d, %d )
    "),
    array($cur_date, $postid, $userid, 0)
));

¿Puedo configurar UPDATE de esta manera usando $wpdb? Soy muy nuevo en la creación de consultas DB personalizadas.

Si no es así, ¿cómo debería/puedo lograr esto?

¡Gracias de antemano!

EDICIÓN ---------------------------------------------------

Nuevo código:

$table = $wpdb->prefix . 'ds_entry_swoons';
$cur_date = date('Y-m-d G:i:s'); 
$rows_affected = $wpdb->query(
    $wpdb->prepare("
        UPDATE {$table}
        SET  removed = %s, post_id = %d, user_id = %d, swoon_status = %d
        WHERE post_id = $postid AND user_id = $userid;",
        $cur_date, $postid, $userid, 0
    )
);
1
Comentarios

Solo usa la función interna de actualización de wpdb. Ésta se encarga de la sanitización por ti.

Andrew Bartel Andrew Bartel
10 ene 2014 18:14:14
Todas las respuestas a la pregunta 3
1

Existe un método dedicado $wpdb->update() que es un asistente conveniente para ejecutar consultas UPDATE y realiza sanitización, llamando internamente a $wpdb->prepare().

10 ene 2014 15:57:54
Comentarios

Tienes razón @Rarst wpdb::update fuente: ... return $this->query( $this->prepare( $sql, $values ) ); : https://developer.wordpress.org/reference/classes/wpdb/update/

hamid araghi hamid araghi
2 oct 2021 14:22:22
10

Corregí un poco tu consulta. Necesita una tabla y una condición WHERE para evitar cambiar todas las filas. Incluso un LIMIT 1 al final no estaría de más.

$rows_affected = $wpdb->query(
    $wpdb->prepare(
        "UPDATE {$table} SET removed = %s, post_id = %d, user_id = %d, status = %d;",
        $cur_date = date('Y-m-d H:i:s'), $postid, $userid, 0
    ) // $wpdb->prepare
); // $wpdb->query

Solo añade el WHERE... en la consulta MySQL. El uso correcto de prepare es:

$wpdb->prepare($format, $arg1, $arg2, ...); // igual que printf()
19 oct 2011 21:55:27
Comentarios

En realidad, LIMIT 1 es muy peligroso con sentencias UPDATE y DELETE. Esto es particularmente cierto si la base de datos es un Maestro en una configuración de Replicación MySQL porque no hay garantía del orden de UPDATE/DELETE en el Esclavo. Las advertencias sobre esto se publicarán en el registro de errores de MySQL del Maestro. Aparte de eso, tu respuesta es esencialmente correcta una vez que @dkmojo añada la cláusula WHERE. +1 !!!

RolandoMySQLDBA RolandoMySQLDBA
19 oct 2011 22:28:32

Si apuntas a un ID de clave primaria o a una combinación de claves únicas... ¿por qué sería peligroso?

EarnestoDev EarnestoDev
19 oct 2011 22:32:52

Esa sería la única excepción. Las claves no únicas serían una historia diferente. MySQL aún puede publicar advertencias en el registro de errores en cualquier caso.

RolandoMySQLDBA RolandoMySQLDBA
19 oct 2011 22:35:07

De hecho escribí un post sobre eso en DBA StackExchange: http://dba.stackexchange.com/questions/1371/problem-with-mysql-subquery/1384#1384. Tiene que ver con la forma en que el Optimizador de MySQL realiza transformaciones de consultas internamente.

RolandoMySQLDBA RolandoMySQLDBA
19 oct 2011 22:37:53

Cierto, pero esto debería ser una decisión consciente. Si sabes que planeas actualizar un solo registro, que yo sepa, es una buena práctica imponer LIMIT 1. Si tienes un número variable de registros para actualizar, nunca uses LIMIT ya que el orden por defecto es... ¡sin ordenar! :)

EarnestoDev EarnestoDev
19 oct 2011 22:44:10

Hay reportes de bugs en el sitio de MySQL para la versión 4.0 (cerrado: http://bugs.mysql.com/bug.php?id=1024) y 5.1 (parche aplicado hace un año: http://bugs.mysql.com/bug.php?id=42415) sobre el uso de UPDATE/DELETE con LIMIT. Incluso con todas las correcciones de bugs relacionadas con LIMIT, la Replicación de MySQL para el Slave todavía puede ser afectada. Aprendí sobre esto solo por el orden de las filas en SELECT: http://dba.stackexchange.com/q/6051/877.

RolandoMySQLDBA RolandoMySQLDBA
19 oct 2011 22:58:57

El uso de LIMIT también puede involucrar tablas temporales si la consulta lo justifica. Todas las tablas temporales generadas por consultas son, por naturaleza, desordenadas como comentaste anteriormente. LIMIT recorre estas tablas temporales, lo que hace que su orden de ejecución y acceso sea diferente entre el Maestro y el Esclavo.

RolandoMySQLDBA RolandoMySQLDBA
19 oct 2011 23:03:42

¡Gracias por los comentarios detallados! Agregué la cláusula WHERE y añadí mi código editado arriba. Pero no estoy seguro de para qué sirven los '{}' alrededor de $table o si son necesarios. Tengo otras consultas que no usan los '{}'. ¿Para qué son los '{}'? ¡Gracias de nuevo!

dkmojo dkmojo
20 oct 2011 19:00:53

@dkmojo {$variable} es la forma correcta de usar variables en "strings" para mantener control total y evitar caracteres no deseados que se interpreten. (Lee aquí)[http://php.net/manual/en/language.types.string.php]. Lee Sintaxis Simple vs Sintaxis Compleja (con llaves) (busca en el texto de la página enlazada). (ejemplo: $table = "{$wpdb->prefix}ds_entry_swoons";)

EarnestoDev EarnestoDev
20 oct 2011 19:07:44

genial, gracias por la información y el enlace. Los había visto antes en el código de plugins pero no estaba seguro de su propósito. Ahora lo sé, y saber es la mitad de la batalla (GI JOE - tenía que decirlo) :)

dkmojo dkmojo
20 oct 2011 21:51:33
Mostrar los 5 comentarios restantes
0

Puedes insertar tantas variables como quieras (%dígito, %string ...)

global $wpdb;
$zz = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->postmeta 
    SET meta_value = '%s'       WHERE post_id = '%d'    OR WHERE post_id = '%d' ", 
                      $value,                    $id_1,                     $id_2   ) );
var_dump($zz); exit;
21 jul 2015 20:54:32