Klauzula RETURNING
Oficjalne dokumenty można przeczytać tutaj.
Wiele razy po wstawieniu rekordów do naszej bazy danych chcemy zwrócić niektóre dane (prawdopodobnie id). Od wersji 3.35.0
(2021-03-12), SQLite obsługuje RETURNING
klauzula, która pozwala zwrócić wiersz wynikowy (lub określone kolumny) dla każdego zmodyfikowanego wiersza bazy danych przez DELETE
, UPDATE
lub INSERT
oświadczenie.
INSERT INTO customers (fullName, birthdateTimestamp, address)
VALUES ('Andrew Mitch', 643911868, '206 Grange Road, Gillingham')
RETURNING *;
Powyższe zapytanie, po wykonaniu, zwróci nam każdą wartość wstawioną do bazy danych, wraz z id
każdego rzędu. W ten sposób możemy uniknąć wykonywania kolejnego SELECT
zapytanie do bazy danych. Całkiem fajnie, co?
Klauzula UPSERT
Oficjalne dokumenty można przeczytać tutaj.
Kolejną fajną małą funkcją jest UPSERT
klauzula. Zostało to dodane w wersji 3.24.0
(2018-06-04) i powoduje to INSERT
zachowywać się jak UPDATE
lub no-op
, w przypadku UNIQUE CONSTRAINT
lub PRIMARY KEY CONSTRAINT
naruszenie.
Aby rozwinąć, załóżmy, że masz action_records
tabela, która zawiera wszystkie akcje uruchomione przez użytkowników w users
tabela, dla konkretnej sesji . Po uruchomieniu nowej akcji chcesz wstawić nowy action_record
bez błędu lub, jeśli istniejący ORAZ ma tę samą sygnaturę czasową sesji (jest to obsługiwane przez ON CONFLICT
klauzuli), zaktualizuj starą. Możesz również opcjonalnie dodać WHERE
oświadczenie, które spowoduje no-op
, jeśli nie zostały spełnione. Poniższe zapytanie powinno wystarczyć:
-- Create users table and assign userID and sessionStartTimestamp as a UNIQUE CONSTRAINT.
DROP TABLE IF EXISTS "action_records";
CREATE TABLE IF NOT EXISTS "action_records" (
"id" INTEGER NOT NULL,
"userID" INTEGER NOT NULL,
"sessionStartTimestamp" INTEGER NOT NULL,
"errorMsg" TEXT,
PRIMARY KEY("id" AUTOINCREMENT),
FOREIGN KEY("userID") REFERENCES "users"("id") ON DELETE CASCADE,
UNIQUE(userID, sessionStartTimestamp)
);
-- Insert new record or update the old one based on UNIQUE_CONSTRAINT OF userID & session_start_timestamp
INSERT INTO action_records (userID, errorMsg, sessionStartTimestamp)
VALUES (258, null, 643911868)
ON CONFLICT(userID, sessionStartTimestamp) -- Conflict when a record for the same user and session exists
DO UPDATE SET errorMsg = 'An error occured'
WHERE errorMsg IS NOT NULL -- This will be a no-op in case there is already an error and you don't want to update it
RETURNING *; -- Optionally adding RETURNING to retrieve any number of columns we want
PODNOSZENIE I ZWROT połączone
Jedną z rzeczy, które bardzo mi się podobało, jest to, że można połączyć te klauzule, po prostu dodając RETURNING *
na końcu zapytania. W ten sposób zostanie zwrócony dowolny wiersz (lub określone kolumny), wstawiony lub zaktualizowany.