W niektórych przypadkach uruchomienie instrukcji UPDATE w środowisku produkcyjnym może uratować sytuację. Jednak zepsuta aktualizacja może być gorsza niż początkowy problem.
Jakie są opcje, oprócz korzystania z testowej bazy danych, aby sprawdzić, co zrobi instrukcja aktualizacji przed jej uruchomieniem?
FOREIGN KEY UPDATE CASCADE
twój sql zawodziA co z transakcjami? Mają funkcję ROLLBACK.
@zobacz https://dev.mysql.com/doc/refman/5.0/en/commit.html
Na przykład:
START TRANSACTION; SELECT * FROM nicetable WHERE somthing=1; UPDATE nicetable SET nicefield='VALUE' WHERE somthing=1; SELECT * FROM nicetable WHERE somthing=1; #check COMMIT; # or if you want to reset changes ROLLBACK; SELECT * FROM nicetable WHERE somthing=1; #should be the old value
Odpowiedź na pytanie od @rickozoe poniżej:
Generalnie te linie nie będą wykonywane raz. W PHP np. Napisałbyś coś takiego (może trochę czyściej, ale chciałem odpowiedzieć szybko ;-)):
$MysqlConnection->query('START TRANSACTION;'); $erg = $MysqlConnection->query('UPDATE MyGuests SET lastname='Doe' WHERE id=2;'); if($erg) $MysqlConnection->query('COMMIT;'); else $MysqlConnection->query('ROLLBACK;');
Innym sposobem byłoby użycie zmiennych MySQL (patrz https://dev.mysql.com/doc/refman/5.7/en/user-variables.htm l i https://stackoverflow.com/a/18499823/1416909 ):
# do some stuff that should be conditionally rollbacked later on SET @v1 := UPDATE MyGuests SET lastname='Doe' WHERE id=2; IF(v1 < 1) THEN ROLLBACK; ELSE COMMIT; END IF;
Ale sugerowałbym użycie opakowań językowych dostępnych w Twoim ulubionym języku programowania.
źródło
Autocommit OFF ...
MySQL
set autocommit=0;
Ustawia automatyczne zatwierdzanie dla bieżącej sesji.
Wykonujesz instrukcję, widzisz, co się zmieniło, a następnie wycofujesz, jeśli jest źle, lub zatwierdzasz, jeśli tego się spodziewałeś!
EDYCJA: Zaletą używania transakcji zamiast uruchamiania zapytania wybierającego jest to, że można łatwiej sprawdzić wynikowy zestaw.
źródło
Wiem, że to powtórzenie innych odpowiedzi, ale ma pewne wsparcie emocjonalne, aby wykonać dodatkowy krok w testowaniu aktualizacji: D
W przypadku aktualizacji testowej hash # jest twoim przyjacielem.
Jeśli masz oświadczenie o aktualizacji, takie jak:
UPDATE wp_history SET history_by="admin" WHERE history_ip LIKE '123%'
Haszujesz AKTUALIZACJĘ i USTAWIASZ do testów, a następnie haszujesz je z powrotem w:
SELECT * FROM #UPDATE wp_history #SET history_by="admin" WHERE history_ip LIKE '123%'
Działa w przypadku prostych instrukcji.
Dodatkowym praktycznie obowiązkowym rozwiązaniem jest uzyskanie kopii (kopii zapasowej duplikatu) przy każdym użyciu update na stole produkcyjnym. Phpmyadmin> operacje> kopiuj: table_yearmonthday. W przypadku tabel <= 100 mln zajmuje to tylko kilka sekund.
źródło
Nie jest to bezpośrednia odpowiedź, ale widziałem wiele sytuacji związanych z danymi prod, których można było uniknąć, wpisując
WHERE
najpierw klauzulę ! CzasamiWHERE 1 = 0
może też pomóc w bezpiecznym złożeniu oświadczenia roboczego. Przydatne może być przyjrzenie się szacunkowemu planowi wykonania, który oszacuje wiersze, na które ma to wpływ. Poza tym w transakcji, którą wycofujesz, jak powiedzieli inni.źródło
WHERE 1 = 0
jest bardziej przenośne, jeśli ktoś napotka to, kto pracuje z innym DBMS. Na przykład SQL Server nie zaakceptujeWHERE FALSE
.W takich przypadkach, które chcesz przetestować, warto skupić się tylko na bieżących wartościach kolumn i wartościach kolumn, które wkrótce zostaną zaktualizowane .
Proszę spojrzeć na poniższy kod, który napisałem, aby zaktualizować ceny WHMCS:
# UPDATE tblinvoiceitems AS ii SELECT ### JUST ii.amount AS old_value, ### FOR h.amount AS new_value ### TESTING FROM tblinvoiceitems AS ii ### PURPOSES. JOIN tblhosting AS h ON ii.relid = h.id JOIN tblinvoices AS i ON ii.invoiceid = i.id WHERE ii.amount <> h.amount ### Show only updatable rows # SET ii.amount = h.amount
W ten sposób wyraźnie porównujemy już istniejące wartości z nowymi wartościami.
źródło
Uruchom zapytanie wybierające na tej samej tabeli ze wszystkimi
where
warunkami stosowanymi w zapytaniu aktualizującym.źródło
zrobić
SELECT
z tego,jak jeśli masz
UPDATE users SET id=0 WHERE name='jan'
przekonwertować na
SELECT * FROM users WHERE name='jan'
źródło
Jeszcze jedną opcją jest poproszenie MySQL o plan zapytań. To mówi ci dwie rzeczy:
W MySQL i większości baz danych SQL polecenie planu zapytania to
describe
, więc należy:describe update ...;
źródło