RETURNING-satsen
Du kan läsa de officiella dokumenten här.
Många gånger kommer vi på att vi vill returnera vissa data (förmodligen id) efter att ha infogat poster i vår databas. Sedan version 3.35.0
(2021-03-12), SQLite stöder RETURNING
sats, som låter dig returnera en resultatrad (eller specifika kolumner) för varje modifierad databasrad med en DELETE
, UPDATE
eller INSERT
uttalande.
INSERT INTO customers (fullName, birthdateTimestamp, address)
VALUES ('Andrew Mitch', 643911868, '206 Grange Road, Gillingham')
RETURNING *;
Ovanstående fråga kommer, efter körning, att returnera alla värden som infogas i databasen, tillsammans med id
av varje rad. På så sätt kan vi undvika att göra en annan SELECT
fråga till databasen. Ganska snyggt, va?
UPSERT-satsen
Du kan läsa de officiella dokumenten här.
En annan trevlig liten funktion är UPSERT
klausul. Detta lades till i version 3.24.0
(2018-06-04) och det orsakar INSERT
att bete sig antingen som en UPDATE
eller en no-op
, i fallet med en UNIQUE CONSTRAINT
eller en PRIMARY KEY CONSTRAINT
överträdelse.
För att utveckla det, låt oss anta att du har en action_records
tabell som innehåller alla åtgärder som aktiveras av användare i users
tabell, för en specifik session . När en ny åtgärd aktiveras vill du antingen infoga en ny action_record
utan fel, eller, om befintlig OCH har samma sessionstidsstämpel (detta hanteras av ON CONFLICT
klausul), uppdatera den gamla. Du kan också valfritt lägga till en WHERE
uttalande som kommer att resultera i en no-op
, om inte uppfyllt. Frågan nedan borde göra det:
-- 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
UPSERT &RETURNERING kombinerat
En sak jag verkligen gillade är det faktum att du kan kombinera dessa klausuler genom att helt enkelt lägga till RETURNING *
i slutet av frågan. På så sätt kommer alla rader (eller specificerade kolumner), antingen infogade eller uppdaterade, att returneras.