Witajcie,
Chciałbym Was zapytać, czy w SQLite pod androidem, istnieje możliwość wykonania instrukcji UPDATE jeśli dany wiersz istnieje lub INSERT jeśli go nie ma. Z tym że nie chcę sprawdzać po ID tylko mam jednej z wartości, mam taką unikalną wartość dla każdego wiersza i w momencie wciśnięcia przycisku chcę wykonać aktualizację wiersza jeśli on już istnieje w bazie lub dodania nowego jeśli nie i jako ten parametr po którym ma sprawdzać czy wiersz istnieje, chcę podawać tą unikalną wartość. Jest to pole typu INTEGER.
wykonaj najpierw select. Jezeli zwroci obiekt to mozesz zrobic update. Jezeli nic nie zwroci (zapytanie puste) to wtedy insert
Zrobiłem coś takiego jak poniżej ale niestety w przypadku SQLite nie chce zadziałać a dziwne bo podobny przykład znalazłem właśnie w dokumentacji do SQLite
IF EXISTS (SELECT * FROM tmp_matches WHERE ROUND = '6')
UPDATE tmp_matches SET TOTAL_SCORE1_AFTER = '13' WHERE ROUND = 6
ELSE
INSERT INTO tmp_matches VALUES TOTAL_SCORE1_AFTER = '13'
nie znam SQLite, ale tak na pierwszy rzut oka to w "insert" nie podstawiasz pola ROUND , które jest w "select" i "update"
Faktycznie popełniłem tu błąd ale nie ma on znaczenia do ogólnego błędu który mi się pojawia. Próbując wykonać to zapytanie w SQLite Manager'ze mam taki komunikat:
SQLiteManager: Likely SQL syntax error: IF EXISTS (SELECT * FROM tmp_matches WHERE ROUND = 6)
UPDATE tmp_matches SET TOTAL_SCORE1_AFTER = '13' WHERE ROUND = 6
ELSE
INSERT INTO tmp_matches VALUES TOTAL_SCORE1_AFTER = '13' [ near "IF": syntax error ]
Exception Name: NS_ERROR_FAILURE
Exception Message: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [mozIStorageConnection.createStatement]
Nie wiem czy dobrze myślę ale obawiam się że instrukcja IF ELSE nie przejdzie.
To co chcesz wykonać nazywa się UPSERT i SQL Lite to osługuje:
INSERT OR REPLACE INTO tmp_matches (ROUND, TOTAL_SCORE1_AFTER)
VALUES (6, 13);
Warto zajrzeć do dokumentacji: http://www.sqlite.org/lang_insert.html
Dodane:
teraz zauważyłem, że nie chcesz po id, torzeba tak:
INSERT OR REPLACE INTO tmp_matches (ID, ROUND, TOTAL_SCORE1_AFTER)
VALUES ((select id from tmp_matches where round=6),6, 13);
fasadin napisał(a):
wykonaj najpierw select. Jezeli zwroci obiekt to mozesz zrobic update. Jezeli nic nie zwroci (zapytanie puste) to wtedy insert
Tylko wtedy, gdy używając odpowiednich mechanizmów zablokujesz równoległość. W standardzie SQL jest MERGE: https://en.wikipedia.org/wiki/Merge_%28SQL%29 robiący to prawidłowo, w SQLite wyżej opisany INSERT OR REPLACE.