Cum se utilizează $wpdb->update pentru mai multe rânduri, similar cu IN în SQL normal
Mă întrebam dacă este posibil să folosești $wpdb->update
pentru a actualiza valori pentru mai multe rânduri, similar cu IN
în SQL "normal".
Vreau să realizez ceva asemănător cu acest exemplu:
UPDATE [tabel]
SET [coloana_1] = [valoare_actualizata]
WHERE [coloana_2] IN ([lista_id_uri_separate_prin_virgula])
Am căutat informații despre cum ar putea funcționa asta, dar nu am găsit nicio întrebare sau răspuns/post de blog care să explice dacă se poate face sau nu.
Deocamdată folosesc o interogare, dar ar fi mai elegant cu o singură linie de cod.

După cum puteți vedea în codul sursă, semnul =
este hardcodat în metoda wpdb::update()
, așadar, în mod implicit, nu este posibil să utilizați IN
pentru metoda de actualizare.
Cea mai simplă metodă de a rezolva această problemă este să utilizați wpdb::query()
cu interogarea SQL dorită, doar asigurați-vă că toate valorile sunt corect escăpate.
Exemplu:
function wpdb_update_in( $table, $data, $where, $format = NULL, $where_format = NULL ) {
global $wpdb;
$table = esc_sql( $table );
if( ! is_string( $table ) || ! isset( $wpdb->$table ) ) {
return FALSE;
}
$i = 0;
$q = "UPDATE " . $wpdb->$table . " SET ";
$format = array_values( (array) $format );
$escaped = array();
foreach( (array) $data as $key => $value ) {
$f = isset( $format[$i] ) && in_array( $format[$i], array( '%s', '%d' ), TRUE ) ? $format[$i] : '%s';
$escaped[] = esc_sql( $key ) . " = " . $wpdb->prepare( $f, $value );
$i++;
}
$q .= implode( $escaped, ', ' );
$where = (array) $where;
$where_keys = array_keys( $where );
$where_val = (array) array_shift( $where );
$q .= " WHERE " . esc_sql( array_shift( $where_keys ) ) . ' IN (';
if( ! in_array( $where_format, array('%s', '%d'), TRUE ) ) {
$where_format = '%s';
}
$escaped = array();
foreach( $where_val as $val ) {
$escaped[] = $wpdb->prepare( $where_format, $val );
}
$q .= implode( $escaped, ', ' ) . ')';
return $wpdb->query( $q );
}
Apoi utilizați-o astfel:
wpdb_update_in(
'posts', // tabela
array( 'post_author' => '1', 'post_status' => 'draft' ), // date
array( 'post_author' => array( '2', '3', '4', '5' ) ), // condiție
array( '%d', '%s' ), // format
'%d' // format condiție
);
SQL-ul executat va fi
UPDATE wp_posts
SET post_author = 1, post_status = 'draft'
WHERE post_author IN (2, 3, 4, 5)

Nu am lucrat prea mult în WP, așa că nu eram conștient de codul sursă. Am să îl salvez pentru referințe viitoare. Îmi place soluția ta și o voi marca ca răspuns.

Am găsit acest lucru util, dar se pare că unele aspecte s-au schimbat de la momentul acestui răspuns. În primul rând, semnătura pentru implode()
a schimbat ordinea parametrilor începând cu PHP 7.4. De asemenea, nu am putut să înțeleg ce era $wpdb->$table
? L-am eliminat în final.

Lucrurile s-au schimbat în 10 ani, da :)
$wpdb->$table
este modul în care obții numele complet al tabelei. Nu ar trebui să folosești, de exemplu, "wp_content"
ci $wpdb->content
, pentru că prefixul s-ar putea schimba, iar în multisite se va schimba.
Aceasta nu s-a schimbat. Dar astăzi avem substituentul %i
pentru a escapa numele tabelelor.
Referitor la %f
, da acesta a fost adăugat relativ recent împreună cu %i
menționat mai sus.
