zmdbzero-maintenance data layer
Docs Benchmarks Anti-patterns OpenAPI
Docs / Schema and ORM

InsertSupported

Insert rows with the query builder, or (preferably) through a repository's create(), which validates the payload against CreateDTO<S> before any SQL is emitted.

Basic insert#

import { trustedTable } from '@zmdb/sql';

qc.insertInto(trustedTable('users')).values({ email: 'a@b.com', role: 'user' }).compile();
INSERT INTO "users" ("email", "role") VALUES ($1, $2)
-- parameters: ['a@b.com', 'user']

Returning the inserted row#

import { trustedTable } from '@zmdb/sql';

qc.insertInto(trustedTable('users')).values({ email: 'a@b.com' }).returning(['id', 'createdAt']).compile();
INSERT INTO "users" ("email") VALUES ($1) RETURNING "id", "createdAt"

SQL Server places its equivalent before VALUES:

INSERT INTO [users] ([email]) OUTPUT INSERTED.[id], INSERTED.[createdAt] VALUES (@p1)

MySQL refuses returning() rather than emitting unsupported SQL.

That also means BaseRepository.create() refuses before driver execution on the MySQL family: its Promise<Entity<T>> contract cannot honestly be satisfied by dropping the clause. Use a lower-level INSERT without returning(), validate the payload explicitly, and perform the read you need.

Through the repository (validated)#

const user = await users.create({ email: 'a@b.com' }); // role defaults applied
// returns Entity<User>
❗ Important

If the payload is invalid, create throws a structured ValidationError and no SQL runs — the driver is never called. Auto-increment PKs and defaulted columns may be omitted from the payload (that is what CreateDTO encodes).

See also batch inserts for multiple statements in one round-trip.