Updating SQL Tables¶
There are a couple ways to update an existing SQL table.
- Use
UPDATEto change rows that already exist. - Use
INSERTwith anON CONFLICThandler to perform an upsert.
UPDATE¶
UPDATE is the standard way to modify data in-place.
This method typically uses a WHERE conditional clause so that it only changes
the rows that meet certain conditions, which is usually what needs to happen
when modifying single rows.
For example, if a specific row in a table called users needed its email
value changed:
WHERE clause is saying to only set the email to new@example.com when the
value of user_id is equal to 42.
Warning
If an UPDATE is used without a WHERE clause, it will update every row
in the table.
This has its use cases, but it can be a very destructive operation without
the WHERE clause.
Only omit the WHERE when the same field in all rows needs to be
homogenized.
INSERT/ON CONFLICT (Upsert)¶
This method is great for combining the functionality of both the creation of, and updating of, rows.
- Creates new rows
- Updates existing rows if the row exists already
For example, doing the same operation as above (updating the email field in
the users table, where the user_id field has the value of 42):
INSERT INTO users (user_id, email)
VALUES (42, 'new@example.com')
ON CONFLICT (user_id)
DO UPDATE SET email = EXCLUDED.email;
-
INSERT INTO users (user_id, email): This says to create a row in theuserstable with two fields:user_idandemail. -
VALUES (42, 'new@example.com'): The values for the two fields (in order). -
ON CONFLICT (user_id) DO: Says "If a row matchinguser_id = 42already exists, do the following." -
UPDATE SET email = EXCLUDED.email;: Do anUPDATE(as above), setting the email to the new value passed inVALUES.-
EXCLUDED.emailis the value that the query attempted to use before the conflict resolution runs. -
If only
emailwas used here withoutEXCLUDED,emailwould refer to the existing row in the table being updated, not the incoming row. -
In PostgreSQL,
ON CONFLICT DO UPDATE,EXCLUDEDis a special alias for the would-be inserted row, soEXCLUDED.emailmeans "Use the new email from the attempted insert."
-
So, if user_id = 42 already exists, update the stored row's email to the
newly provided one. If only email was used, the nnew incoming value would not
be clearly referenced, and in most cases would refer to the current row's
email value instead.