INSERT JEŚLI NIE ISTNIEJE INNA AKTUALIZACJA?
Znalazłem kilka" byłoby "rozwiązań dla klasycznego" jak wstawić nowy rekord lub zaktualizować jeden, jeśli już istnieje", ale nie mogę dostać żadnego z nich do pracy w SQLite.
Mam tabelę zdefiniowaną następująco:
CREATE TABLE Book
ID INTEGER PRIMARY KEY AUTOINCREMENT,
Name VARCHAR(60) UNIQUE,
TypeID INTEGER,
Level INTEGER,
Seen INTEGER
Chcę dodać rekord o unikalnej nazwie. Jeśli nazwa już istnieje, chcę zmodyfikować pola.
Czy ktoś może mi powiedzieć jak to zrobić?8 answers
Spójrz na http://sqlite.org/lang_conflict.html .
Chcesz coś w stylu:
insert or replace into Book (ID, Name, TypeID, Level, Seen) values
((select ID from Book where Name = "SearchName"), "SearchName", ...);
Należy zauważyć, że każde pole spoza listy Wstaw zostanie ustawione na NULL, jeśli wiersz już istnieje w tabeli. Z tego powodu dla kolumny ID
istnieje podzbiór: w przypadku zastąpienia polecenie ustawiłoby ją na NULL, a następnie przydzielono nowe ID.
To podejście można również zastosować, jeśli chcemy pozostawić tylko określone wartości pola, jeśli wiersz w przypadek zastępczy, ale ustaw pole na NULL w przypadku wstawienia.
Na przykład, zakładając, że chcesz zostawić Seen
w spokoju:
insert or replace into Book (ID, Name, TypeID, Level, Seen) values (
(select ID from Book where Name = "SearchName"),
"SearchName",
5,
6,
(select Seen from Book where Name = "SearchName"));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 06:34:43
Należy użyć polecenia INSERT OR IGNORE
, a następnie polecenia {[2] }:
W poniższym przykładzie name
jest kluczem podstawowym:
INSERT OR IGNORE INTO my_table (name, age) VALUES ('Karen', 34)
UPDATE my_table SET age = 34 WHERE name='Karen'
Pierwsze polecenie wstawi rekord. Jeśli rekord istnieje, zignoruje błąd spowodowany konfliktem z istniejącym kluczem głównym.
Drugie polecenie zaktualizuje rekord (który teraz na pewno istnieje)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-20 23:12:57
Musisz ustawić ograniczenie na stole, aby wywołać konflikt " ", który następnie rozwiązujesz, wykonując zastąpienie:
CREATE TABLE data (id INTEGER PRIMARY KEY, event_id INTEGER, track_id INTEGER, value REAL);
CREATE UNIQUE INDEX data_idx ON data(event_id, track_id);
Wtedy możesz wydać:
INSERT OR REPLACE INTO data VALUES (NULL, 1, 2, 3);
INSERT OR REPLACE INTO data VALUES (NULL, 2, 2, 3);
INSERT OR REPLACE INTO data VALUES (NULL, 1, 2, 5);
"Wybierz * z danych" da ci:
2|2|2|3.0
3|1|2|5.0
Zauważ, że data.id jest "3", a nie "1", ponieważ REPLACE usuwa i wstawia, a nie aktualizuje. Oznacza to również, że musisz upewnić się, że zdefiniujesz wszystkie niezbędne kolumny lub otrzymasz nieoczekiwane wartości NULL.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 10:54:28
Najpierw zaktualizuj. If affected row count = 0 then insert it. Jest najłatwiejszy i odpowiedni dla wszystkich RDBMS .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-03 10:50:07
INSERT OR REPLACE
zastąpi pozostałe pola (TypeID
, Level
) do wartości domyślnej.
INSERT OR REPLACE INTO book(id, name) VALUES(1001, 'Programming')
Używam tego
INSERT OR IGNORE INTO book(id) VALUES(1001);
UPDATE book SET name = 'Programming' WHERE id = 1001;
Możesz również użyć
INSERT OR REPLACE INTO book (id, name)
VALUES (1001, 'Programming',
(SELECT typeid FROM book WHERE id = 1001),
(SELECT level FROM book WHERE id = 1001),
)
Ale myślę, że pierwsza metoda łatwiejsza do odczytania
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-22 04:19:07
Jeśli nie masz klucza głównego, możesz wstawić, jeśli nie istnieje, a następnie wykonać aktualizację. Tabela musi zawierać co najmniej jeden wpis przed jej użyciem.
INSERT INTO Test
(id, name)
SELECT
101 as id,
'Bob' as name
FROM Test
WHERE NOT EXISTS(SELECT * FROM Test WHERE id = 101 and name = 'Bob') LIMIT 1;
Update Test SET id='101' WHERE name='Bob';
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-01 18:04:35
Wierzę, że chcesz UPSERT .
"Wstaw lub zastąp" bez dodatkowych sztuczek w tej odpowiedzi zresetuje pola, których nie określisz na wartość NULL lub inną wartość domyślną. (Takie zachowanie INSERT lub REPLACE nie przypomina UPDATE; jest dokładnie takie samo jak INSERT, ponieważ w rzeczywistości jest INSERT; jednak jeśli to, co chciałeś, to UPDATE-if-istnieje, prawdopodobnie chcesz semantyki aktualizacji i będziesz nieprzyjemnie zaskoczony faktycznym wynikiem.)
Sztuczka z sugerowanego UPSERT implementacja polega zasadniczo na użyciu Wstaw lub zamień, ale określ wszystkie pola, używając osadzonych klauzul SELECT, aby pobrać bieżącą wartość dla pól, których nie chcesz zmieniać.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:31
Myślę, że warto zwrócić uwagę, że może wystąpić nieoczekiwane zachowanie, jeśli nie do końca rozumiesz, jak Klucz podstawowy i UNIQUE oddziałują.
Jako przykład, jeśli chcesz wstawić rekord tylko wtedy, gdy poleNAME nie jest aktualnie zajęte, a jeśli tak, chcesz, aby wyjątek ograniczenia miał ci powiedzieć, to INSERT lub REPLACE nie wyrzuci i wyjątek, a zamiast tego rozwiąże unikalne ograniczenie poprzez zastąpienie sprzeczny rekord (istniejący rekord o tej samej nazwie ). Gaspard ' s pokazuje to bardzo dobrze w swojej odpowiedzi powyżej.
Jeśli chcesz użyć wyjątku ograniczenia do fire, musisz użyć INSERT i polegać na osobnym poleceniu UPDATE, aby zaktualizować rekord, gdy wiesz, że nazwa nie jest zajęta.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:30