La clausola RESTITUTIVA
Puoi leggere i documenti ufficiali qui.
Molte volte ci troviamo a voler restituire dei dati (probabilmente l'id) dopo aver inserito dei record nel nostro database. Dalla versione 3.35.0
(12-03-2021), SQLite supporta il RETURNING
clausola, che consente di restituire una riga di risultato (o colonne specifiche) per ogni riga del database modificata mediante un DELETE
, UPDATE
o INSERT
dichiarazione.
INSERT INTO customers (fullName, birthdateTimestamp, address)
VALUES ('Andrew Mitch', 643911868, '206 Grange Road, Gillingham')
RETURNING *;
La query di cui sopra, dopo l'esecuzione, ci restituirà ogni valore inserito nel database, insieme all'id
di ogni riga. In questo modo possiamo evitare di fare un altro SELECT
interrogazione al database. Abbastanza pulito, eh?
La clausola UPSERT
Puoi leggere i documenti ufficiali qui.
Un'altra simpatica funzionalità è UPSERT
clausola. Questo è stato aggiunto nella versione 3.24.0
(04-06-2018) e provoca INSERT
comportarsi come un UPDATE
o un no-op
, in caso di UNIQUE CONSTRAINT
o un PRIMARY KEY CONSTRAINT
violazione.
Per elaborare, supponiamo di avere un action_records
tabella che contiene tutte le azioni attivate dagli utenti in users
tabella, per una sessione specifica . Quando viene attivata una nuova azione, vuoi inserire un nuovo action_record
senza errori o, se esistente AND ha lo stesso timestamp della sessione (questo è gestito da ON CONFLICT
clausola), aggiornare quella precedente. Puoi anche aggiungere facoltativamente un WHERE
dichiarazione che risulterà in un no-op
, se non soddisfatto. La query seguente dovrebbe farlo:
-- 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 &RESO combinati
Una cosa che mi è davvero piaciuta è il fatto che puoi combinare queste clausole semplicemente aggiungendo RETURNING *
alla fine della domanda. In questo modo verrà restituita qualsiasi riga (o colonna specificata), inserita o aggiornata.