UPDATE
db.update(table) builds an UPDATE query. It supports multi-table updates via FROM, CTEs, a WHERE clause, an optional RETURNING clause, and runtime overrides for SET and WHERE.
const { query, args } = db.update('user')
.set({ active: false })
.where({ id: 5 })
.prepare()();UPDATE user
SET active = $1
WHERE (id = $2).set()
Specifies the columns to update and their new values. Keys are column names, values are the new data.
db.update('user')
.set({ name: 'Alice Updated', email: 'new@example.com' })
.where({ id: 1 })
.prepare()()UPDATE user
SET name = $1,
email = $2
WHERE (id = $3).where()
Same syntax as SELECT. See the WHERE reference in the main README.
db.update('post')
.set({ published: false })
.where({ author_id: 1, '>=:views': 0 })
.prepare()()Column-to-column comparisons with col():
import { col } from 'helice';
db.update('post')
.set({ published: false })
.where({ 'post.author_id': col('user.id') })
.prepare()().using() — multi-table UPDATE
PostgreSQL supports UPDATE … FROM to join another table into the update. Pass the table names to .using(), then reference them in .where().
import { col } from 'helice';
db.update('post')
.using(['user'])
.set({ published: false })
.where({ 'post.author_id': col('user.id'), 'user.active': false })
.prepare()()UPDATE post
SET published = $1
FROM user
WHERE (post.author_id = user.id AND user.active = $2).with() — CTEs
Prepends a WITH clause. Useful when the update depends on a derived set of rows.
db.update('post')
.with('inactive_users', db.select('user').where({ active: false }))
.using(['inactive_users'])
.set({ published: false })
.where({ 'post.author_id': col('inactive_users.id') })
.prepare()()WITH inactive_users AS (
SELECT *
FROM user
WHERE (active = $1)
)
UPDATE post
SET published = $2
FROM inactive_users
WHERE (post.author_id = inactive_users.id)Parameter numbering across CTEs and the main query is handled automatically.
Runtime CTE args
Pass a prepare options object as the third argument to .with() to enable runtime overrides inside the CTE. The CTE's args are passed under the alias key at call time:
const q = db.update('post')
.with(
'target_users',
db.select('user').where({ active: true }),
{ where: true }
)
.using(['target_users'])
.set({ published: false })
.where({ 'post.author_id': col('target_users.id') })
.prepare();
q({ target_users: { where: { '~~:name': 'Alice%' } } }).in() / .notIn()
Adds a col IN (subquery) or col NOT IN (subquery) condition. Parameters from the IN subquery are numbered after SET values.
// Unpublish posts by inactive users
db.update('post')
.set({ published: false })
.in('author_id', db.select('user').field(['id']).where({ active: false }))
.prepare()()
// SET published = $1
// WHERE (author_id IN (SELECT id FROM user WHERE (active = $2)))Can be combined with .where():
db.update('post')
.set({ published: false })
.in('author_id', db.select('user').field(['id']).where({ active: false }))
.where({ '>=:views': 100 })
.prepare()()
// WHERE (author_id IN (...) AND views >= $3).returning()
Appends RETURNING to the query:
db.update('user')
.set({ active: false })
.where({ id: 5 })
.returning(['id', 'name', 'active'])
.prepare()()UPDATE user
SET active = $1
WHERE (id = $2)
RETURNING id, name, active.build() / .execute()
const { query, args } = db.update('user').set({ active: false }).where({ id: 5 }).build();
await db.update('user').set({ active: false }).where({ id: 5 })
.execute((q, a) => pgClient.query(q, a));Both use static SET + WHERE only. For runtime set/where, use .prepare().
.prepare() — runtime options
| Option | Type | Behaviour |
|---|---|---|
set |
true |
Supply the SET values at call time |
where |
true |
Runtime WHERE merged AND with static WHERE |
where |
{ [table]: true | string[] } |
Same, restricted to specific tables/columns |
Examples
// Runtime SET + runtime WHERE
const updateUser = db.update('user')
.prepare({ set: true, where: true });
updateUser({ set: { name: 'Dave', active: true }, where: { id: 10 } })
// Restricted runtime WHERE — only 'id' column allowed
const updateUser = db.update('user')
.prepare({ set: true, where: { user: ['id'] } });
updateUser({ set: { name: 'Dave' }, where: { id: 10 } })
// TypeScript will reject where: { email: '...' } — not in the restriction list
// Static SET + runtime WHERE merged AND
const publishPosts = db.update('post')
.set({ published: true })
.where({ author_id: 1 })
.prepare({ where: true });
publishPosts({ where: { '>=:views': 100 } })
// SET published = $1 WHERE (author_id = $2 AND views >= $3)