WPDB Insert sau Update dacă există
Nu sunt foarte familiarizat cu WPDB sau SQL în general, dar am un tabel personalizat pentru proiectul meu și încerc să atribui niște metadate în acesta. Ceea ce aș "dori" să se întâmple este ca dacă există deja un rând, să-l actualizeze, iar dacă nu, să insereze unul nou. Am citit atât despre Insert cât și despre Update în Codex-ul WPDB, dar niciunul nu a abordat o situație de tipul "una sau alta". M-am gândit că aș putea lucra cu update, așa că codul meu până acum arată astfel:
$wpdb->update(
$wpdb->prepare(
$wpdb->prefix.'item_info',
array(
'post_id' => $post_id,
'item_stock' => $item_stock
),
array('post_id' => $post_id)
)
);
Are WordPress ceva de genul "DACĂ există Update, ALTFEL Insert", sau trebuie să rulez SQL personalizat pentru a realiza acest lucru, sau trebuie să interoghez mai întâi baza de date pentru a vedea dacă există un ID în tabelul meu și APOI să decid dacă să-l actualizez sau să-l inserez?

Ai încercat $wpdb->replace
. Conform WP Codex:
Înlocuiește un rând într-o tabelă dacă acesta există sau inserează un rând nou în tabelă dacă rândul nu exista deja.
Am testat personal în câteva plugin-uri și funcționează atunci când încerci să eviți erori de duplicare a ID-urilor unice, etc.

Aceasta a funcționat pentru mine în timp ce interogarea personalizată nu a funcționat - mulțumesc pentru menționarea funcției replace()

este important de menționat că $wpdb->replace
suprascrie întreaga înregistrare în mod distructiv, în timp ce $wpdb->update
actualizează doar câmpurile specifice incluse în array-ul $data

Această funcție nu înlocuiește rândurile pentru mine în acest moment. Ea duplică aceleași rânduri. Poate fi câmpul PRIMARY KEY (id) cauza care împiedică înlocuirea să se întâmple? Nu găsesc informații despre asta în Codex.

Am rezolvat: Pentru a atenua această problemă de înlocuire, este necesar să aplici constrângerea UNIQUE pe anumite coloane la crearea tabelului, făcând astfel posibile rândurile unice.

În primul rând, folosești prepare
incorect. Se pare că ai argumentele lui $wpdb->update
înfășurate în $wpdb->prepare
în felul acesta. Asta nu va funcționa. În esență, îi transmiți lui update
un singur argument - rezultatul lui prepare
. Încearcă ceva simplu ca în exemplul următor și vei vedea de ce nu funcționează:
$post_id = 123;
$item_stock = 567;
var_dump(
$wpdb->prepare(
$wpdb->prefix.'item_info',
array(
'post_id' => $post_id,
'item_stock' => $item_stock
),
array('post_id' => $post_id)
)
);
Și $wpdb->update()
execută prepare
pentru tine.
În al doilea rând, dacă aș fi în locul tău, aș sări peste funcțiile helper inutile și aș scrie o interogare corectă ON DUPLICATE KEY UPDATE
:
$sql = "INSERT INTO {$wpdb->prefix}item_info (post_id,item_stock) VALUES (%d,%s) ON DUPLICATE KEY UPDATE item_stock = %s";
// var_dump($sql); // debug
$sql = $wpdb->prepare($sql,$post_id,$item_stock,$item_stock);
// var_dump($sql); // debug
$wpdb->query($sql);
Aceasta presupune că post_id
este un UNIQUE
index sau PRIMARY KEY
. Dacă structura tabelului tău este ce cred eu, lasă baza de date să se ocupe de asta.

Asta a fost incredibil de util... Mulțumesc pentru timpul acordat, s_ha_dum!

Prepare returnează false pentru mine - nicio altă eroare de bază de date. Dacă rulez query-ul manual în phpmyadmin, funcționează conform așteptărilor. De asemenea, am verificat că variabilele sunt ceea ce ar trebui să fie... Ai vreo idee?

Puteți încerca să actualizați tabelul folosind $wpdb->update
. În codul următor folosesc id-ul, dar puteți folosi orice criteriu.
$result = $wpdb->update($tableName, $info, array('id' => $info["id"]));
//Dacă nu găsește nimic de actualizat, va încerca să creeze înregistrarea.
if ($result === FALSE || $result < 1) {
$wpdb->insert($tableName, $info);
}
Rezultate posibile pentru Update()
$result === FALSE
: Eșec$result === 0
: Succes, dar nimic actualizat$result > 1
: Succes și actualizat
