sql >> Database >  >> RDS >> SQLite

Korte post over de SQLite UPSERT en de nieuwe RETURNING-clausule.

De RETURNING-clausule

U kunt de officiële documenten hier lezen.

Vaak merken we dat we wat gegevens (waarschijnlijk de id) willen retourneren nadat we records in onze database hebben ingevoegd. Sinds versie 3.35.0 (2021-03-12), SQLite ondersteunt de RETURNING clausule, waarmee u een resultaatrij (of specifieke kolommen) kunt retourneren voor elke gewijzigde databaserij door een DELETE , UPDATE of INSERT verklaring.

INSERT INTO customers (fullName, birthdateTimestamp, address) 
VALUES ('Andrew Mitch', 643911868, '206 Grange Road, Gillingham') 
RETURNING *;

De bovenstaande query zal ons, na uitvoering, elke waarde retourneren die in de database is ingevoegd, samen met de id van elke rij. Op deze manier kunnen we voorkomen dat we nog een SELECT . maken opvragen in de database. Best netjes, toch?

De UPSERT-clausule

U kunt de officiële documenten hier lezen.

Een andere leuke kleine functie is de UPSERT clausule. Dit is toegevoegd in versie 3.24.0 (2018-06-04) en het veroorzaakt INSERT om zich te gedragen als een UPDATE of een no-op , in het geval van een UNIQUE CONSTRAINT of een PRIMARY KEY CONSTRAINT overtreding.

Laten we, om uit te werken, aannemen dat je een action_records . hebt tabel met alle acties die zijn uitgevoerd door gebruikers in de users tafel, voor een specifieke sessie . Wanneer een nieuwe actie wordt geactiveerd, wil je ofwel een nieuw action_record invoegen zonder fout, of, als de bestaande AND dezelfde sessietijdstempel heeft (dit wordt afgehandeld door de ON CONFLICT clausule), update de oude. Je kunt optioneel ook een WHERE . toevoegen statement wat resulteert in een no-op , indien niet voldaan. De onderstaande query zou het moeten doen:

-- 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

UPERT &RETOUR gecombineerd

Een ding dat ik erg leuk vond, is het feit dat je die clausules kunt combineren door simpelweg RETURNING * toe te voegen aan het einde van de vraag. Op deze manier wordt elke rij (of gespecificeerde kolommen), ingevoegd of bijgewerkt, geretourneerd.


  1. TypeORM subquery's

  2. Hoe een tafel laten vallen als deze bestaat?

  3. Waarom wordt de uitvoeringstijd van de opgeslagen procedure in Oracle aanzienlijk verlengd, afhankelijk van hoe deze wordt uitgevoerd?

  4. PDO MySQL:voeg meerdere rijen in één query in