Klauzule RETURNING
Oficiální dokumenty si můžete přečíst zde.
Mnohokrát se přistihneme, že po vložení záznamů do naší databáze chceme vrátit nějaká data (pravděpodobně id). Od verze 3.35.0
(2021-03-12), SQLite podporuje RETURNING
klauzule, která vám umožňuje vrátit řádek výsledku (nebo konkrétní sloupce) pro každý upravený řádek databáze pomocí DELETE
, UPDATE
nebo INSERT
prohlášení.
INSERT INTO customers (fullName, birthdateTimestamp, address)
VALUES ('Andrew Mitch', 643911868, '206 Grange Road, Gillingham')
RETURNING *;
Výše uvedený dotaz nám po provedení vrátí každou hodnotu vloženou do databáze spolu s id
z každého řádku. Tímto způsobem se můžeme vyhnout dalšímu SELECT
dotaz do databáze. Docela pěkné, co?
Klauzule UPSERT
Oficiální dokumenty si můžete přečíst zde.
Další příjemnou funkcí je UPSERT
doložka. Toto bylo přidáno ve verzi 3.24.0
(2018-06-04) a způsobí to INSERT
chovat se buď jako UPDATE
nebo no-op
, v případě UNIQUE CONSTRAINT
nebo PRIMARY KEY CONSTRAINT
porušení.
Pro upřesnění předpokládejme, že máte action_records
tabulka, která obsahuje všechny akce spuštěné uživateli v users
tabulky, pro konkrétní relaci . Když je spuštěna nová akce, chcete buď vložit nový action_record
bez chyby, nebo pokud existuje A má stejné časové razítko relace (toto řeší ON CONFLICT
doložka), aktualizujte starou. Volitelně můžete také přidat WHERE
příkaz, který bude mít za následek no-op
, pokud není splněno. Měl by to udělat následující dotaz:
-- 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
Kombinace UPSERT &RETURNING
Jedna věc, která se mi opravdu líbila, je skutečnost, že můžete tyto klauzule kombinovat jednoduchým přidáním RETURNING *
na konci dotazu. Tímto způsobem bude vrácen jakýkoli řádek (nebo zadané sloupce), ať už vložené nebo aktualizované.