WPDB Insert lub jeśli istnieje Aktualizacja

21

Nie jestem obco zaznajomiony z WPDB lub SQL w ogóle, ale mam niestandardową tabelę dla mojego projektu i próbuję przypisać do niej metadane. To, co „chciałbym” zrobić, to jeśli istnieje wiersz, zaktualizuj go, a jeśli nie, wstaw go. Przeczytałem zarówno Wstawianie, jak i Aktualizuj w Kodeksie WPDB, ale tak naprawdę żaden z nich nie znalazł się w sytuacji „albo”, albo Myślałem, że mogę pracować z aktualizacją, więc mój kod do tej pory wygląda następująco:

$wpdb->update(
    $wpdb->prepare(
        $wpdb->prefix.'item_info',
        array(
            'post_id'       => $post_id,
            'item_stock'    => $item_stock
        ),
        array('post_id' => $post_id)
    )
);

Czy WordPress ma coś takiego jak „JEŚLI istnieje aktualizacja, Wstawianie ELSE”, czy muszę uruchomić niestandardowy SQL, aby to osiągnąć, czy też muszę najpierw zapytać bazę danych, aby sprawdzić, czy w mojej tabeli istnieje identyfikator, NASTĘPNIE zdecydować, czy zaktualizować to czy wstawić?

Howdy_McGee
źródło

Odpowiedzi:

23

Po pierwsze, używasz preparenieprawidłowo. Wygląda na to, że masz takie $wpdb->updateargumenty $wpdb->prepare. To nie zadziała. W efekcie przekazujesz updatepojedynczy argument - wynik działania prepare. Wypróbuj coś prostego, takiego jak poniżej, a zobaczysz, dlaczego to nie zadziała:

$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()biegnie preparedla ciebie .

Po drugie, jeśli to byłbym ja, pomijam wzdęcia funkcji pomocnika i piszę prawidłowe ON DUPLICATE KEY UPDATEzapytanie:

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

Zakłada się, że post_idjest to UNIQUEindeks lubPRIMARY KEY . Jeśli twoja struktura tabeli jest taka, jak myślę, pozwól bazie danych ją obsłużyć.

s_ha_dum
źródło
To było niezwykle przydatne ... Dzięki za poświęcony czas s_ha_dum!
Jake
Przygotuj zwraca false dla mnie - żadnych innych błędów db. Jeśli zapytanie zostanie uruchomione ręcznie w phpmyadmin, działa zgodnie z oczekiwaniami. Sprawdziłem również, że zmienne są takie, jakie powinny być. Jakieś pomysły?
trainoasis
1
Co jeśli post_id nie jest KLUCZEM PODSTAWOWYM?
Mike Kormendy
18

Czy próbowałeś $wpdb->replace. Według WP Codex:

Zamień wiersz w tabeli, jeśli istnieje, lub wstaw nowy wiersz do tabeli, jeśli wiersz jeszcze nie istnieje.

Próbowałem się w niektórych wtyczkach i działa to, gdy próbuję uniknąć błędów powielania unikalnych identyfikatorów itp.

Więcej informacji w kodeksie

e-crespo
źródło
Działa
To jest poprawna odpowiedź na pytanie.
Tyler Jones,
6
warto zauważyć, że $wpdb->replacejest to destrukcyjne zastąpienie całego rekordu, podczas gdy $wpdb->updateaktualizuje tylko określone pola zawarte w $datatablicy
MatthewLee
0

Powinieneś sprawdzić, czy wiersz istnieje pierwszy.

Najprawdopodobniej będziesz chciał uzyskać identyfikator lub klucz podstawowy dla wiersza, który próbujesz zaktualizować, a $wpdb->updatejeśli tak, $wpdb->insertto nie

felipelawinz
źródło
14
Przykład, jak sprawdzić, czy istnieje identyfikator lub klucz podstawowy, naprawdę uczyniłby to przydatną odpowiedzią. To prawie jak powtórzenie pytania.
Jake