SQLite UPSERT / UPDATE OR INSERT

后端 未结 7 748
时光说笑
时光说笑 2020-11-28 18:08

I need to perform UPSERT / INSERT OR UPDATE against a SQLite Database.

There is the command INSERT OR REPLACE which in many cases can be useful. But if you want to k

7条回答
  •  情话喂你
    2020-11-28 18:39

    Here's an approach that doesn't require the brute-force 'ignore' which would only work if there was a key violation. This way works based on any conditions you specify in the update.

    Try this...

    -- Try to update any existing row
    UPDATE players
    SET age=32
    WHERE user_name='steven';
    
    -- If no update happened (i.e. the row didn't exist) then insert one
    INSERT INTO players (user_name, age)
    SELECT 'steven', 32
    WHERE (Select Changes() = 0);
    

    How It Works

    The 'magic sauce' here is using Changes() in the Where clause. Changes() represents the number of rows affected by the last operation, which in this case is the update.

    In the above example, if there are no changes from the update (i.e. the record doesn't exist) then Changes() = 0 so the Where clause in the Insert statement evaluates to true and a new row is inserted with the specified data.

    If the Update did update an existing row, then Changes() = 1 (or more accurately, not zero if more than one row was updated), so the 'Where' clause in the Insert now evaluates to false and thus no insert will take place.

    The beauty of this is there's no brute-force needed, nor unnecessarily deleting, then re-inserting data which may result in messing up downstream keys in foreign-key relationships.

    Additionally, since it's just a standard Where clause, it can be based on anything you define, not just key violations. Likewise, you can use Changes() in combination with anything else you want/need anywhere expressions are allowed.

提交回复
热议问题