wpdb->prepare e UPDATE mysql - come si fa?

19 ott 2011, 20:17:30
Visualizzazioni: 39K
Voti: 0

Sto cercando di impostare una data/ora di 'rimozione' in una query di un plugin ma non sono sicuro di come usare UPDATE SET con $wpdb->prepare.

Ecco la mia query:

$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)
));

Posso impostare UPDATE in questo modo usando $wpdb? Sono molto nuovo nelle query DB personalizzate.

Se no, come dovrei/posso realizzarlo?

Grazie in anticipo!

MODIFICA ---------------------------------------------------

Nuovo codice:

$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
Commenti

Basta utilizzare la funzione di aggiornamento interna di wpdb. Gestisce la sanificazione per te.

Andrew Bartel Andrew Bartel
10 gen 2014 18:14:14
Tutte le risposte alla domanda 3
1

Esiste un metodo dedicato $wpdb->update() che è sia un comodo helper per eseguire query UPDATE sia esegue la sanificazione, chiamando internamente $wpdb->prepare().

10 gen 2014 15:57:54
Commenti

Hai ragione @Rarst wpdb::update fonte: ... return $this->query( $this->prepare( $sql, $values ) ); : https://developer.wordpress.org/reference/classes/wpdb/update/

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

Ho sistemato in qualche modo la tua query. Ha bisogno di una tabella e di una condizione WHERE per evitare di modificare tutte le righe. Anche un LIMIT 1 alla fine non farebbe male.

$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

Basta aggiungere il WHERE... nella query MySQL. L'uso corretto di prepare è:

$wpdb->prepare($format, $arg1, $arg2, ...); // proprio come printf()
19 ott 2011 21:55:27
Commenti

In realtà, LIMIT 1 è molto pericoloso con le istruzioni UPDATE e DELETE. Questo è particolarmente vero se il database è un Master in una configurazione di Replicazione MySQL perché non c'è alcuna garanzia sull'ordine degli UPDATE/DELETE sullo Slave. Gli avvisi su questo verranno registrati nel log degli errori di MySQL del Master. A parte questo, la tua risposta è essenzialmente corretta una volta che @dkmojo aggiunge la clausola WHERE. +1 !!!

RolandoMySQLDBA RolandoMySQLDBA
19 ott 2011 22:28:32

Se si punta a un ID chiave primaria o a una combinazione di chiavi univoche... perché sarebbe pericoloso?

EarnestoDev EarnestoDev
19 ott 2011 22:32:52

Quello sarebbe l'unica eccezione. Le chiavi non univoche sarebbero un'altra storia. MySQL potrebbe comunque registrare avvisi nel log degli errori in entrambi i casi.

RolandoMySQLDBA RolandoMySQLDBA
19 ott 2011 22:35:07

In realtà ho scritto un post su questo argomento nel DBA StackExchange: http://dba.stackexchange.com/questions/1371/problem-with-mysql-subquery/1384#1384. Ha a che fare con il modo in cui l'ottimizzatore di MySQL esegue le trasformazioni delle query sotto il cofano.

RolandoMySQLDBA RolandoMySQLDBA
19 ott 2011 22:37:53

Vero, ma questa dovrebbe essere una decisione consapevole. Se sai che intendi aggiornare un singolo record, AFAIK, è buona pratica imporre il LIMIT 1. Se hai un numero variabile di record da aggiornare, non usare mai il LIMIT poiché l'ordinamento predefinito è... non ordinato :)

EarnestoDev EarnestoDev
19 ott 2011 22:44:10

Ci sono segnalazioni di bug nel sito di mysql per la versione 4.0 (chiuso: http://bugs.mysql.com/bug.php?id=1024) e 5.1 (patch applicata un anno fa: http://bugs.mysql.com/bug.php?id=42415) riguardo l'uso di UPDATE/DELETE con LIMIT. Anche con tutte le correzioni di bug relative al LIMIT, la replica MySQL per lo Slave può ancora essere vittima di problemi. Ho appreso questo solo dall'ordine delle righe SELEZIONATE: http://dba.stackexchange.com/q/6051/877.

RolandoMySQLDBA RolandoMySQLDBA
19 ott 2011 22:58:57

L'uso di LIMIT può anche coinvolgere tabelle temporanee se la query lo richiede. Tutte le tabelle temporanee generate dalle query sono, per loro natura, non ordinate come hai commentato in precedenza. LIMIT scorre attraverso queste tabelle temporanee rendendo il suo ordine di esecuzione e accesso diverso dal Master allo Slave.

RolandoMySQLDBA RolandoMySQLDBA
19 ott 2011 23:03:42

Grazie per il feedback dettagliato! Ho aggiunto la clausola WHERE e ho inserito il mio codice modificato sopra. Ma non sono sicuro dello scopo delle '{}' attorno a $table o se siano necessarie. Ho altre query che non usano le '{}'. A cosa servono le '{}'? Grazie ancora!

dkmojo dkmojo
20 ott 2011 19:00:53

@dkmojo {$variabile} è il modo corretto per usare le variabili nelle "stringhe" per mantenere il controllo completo ed evitare che vengano analizzati caratteri indesiderati. (Leggi qui)[http://php.net/manual/en/language.types.string.php]. Leggi Sintassi Semplice vs Sintassi Complessa (con parentesi graffe) (cerca nel testo della pagina linkata). (esempio: $table = "{$wpdb->prefix}ds_entry_swoons";)

EarnestoDev EarnestoDev
20 ott 2011 19:07:44

figo grazie per l'approfondimento e il link. Li avevo già visti nel codice dei plugin ma non ero sicuro del loro scopo. Ora lo so, e sapere è metà dell'opera (GI JOE - dovevo farlo) :)

dkmojo dkmojo
20 ott 2011 21:51:33
Mostra i restanti 5 commenti
0

Puoi inserire tutte le variabili che vuoi (%digit, %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 lug 2015 20:54:32