SQLite
 sql >> Database >  >> RDS >> SQLite

Post rapido su SQLite UPSERT e la nuova clausola RETURNING.

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.