Delete¶
This page explains how to construct SQL DELETE statements using ts-sql-query. It covers conditional deletions, returning deleted values using returning, deleting with additional tables via using, and bulk deletions using mapped constant values. It also highlights safety mechanisms to avoid unintended full-table deletions.
General delete¶
const deleteCustomer = connection.deleteFrom(tCustomer)
.where(tCustomer.id.equals(10))
.executeDelete();
The executed query is:
The parameters are: [ 10 ]
The result type is a promise with the number of deleted rows:
Security constraint
ts-sql-query will reject the execution of a delete statement if, for some reason, it ends without a WHERE clause. If you want to allow a delete without where, you must call connection.deleteAllowingNoWhereFrom(...) instead of connection.deleteFrom(...) when you start writing the sentence.
Delete returning¶
If you are using PostgreSQL, modern SQLite, SQL Server, modern MariaDB or Oracle, you can return values of the deleted record in the same query using the returning or returningOneColumn methods.
const deletedAcmeCompany = connection.deleteFrom(tCompany)
.where(tCompany.name.equals('ACME'))
.returning({
id: tCompany.id,
name: tCompany.name
})
.executeDeleteOne()
The executed query is:
The parameters are: [ 'ACME' ] (On Oracle, output parameters are added at the corresponding position with the structure {dir:3003})
The result type is a promise with the information of the deleted rows:
Other options
You can project optional values in objects as always-required properties that allow null calling projectingOptionalValuesAsNullable() immediately after returning(...).
You can execute the query using:
executeDeleteNoneOrOne(): Promise<RESULT | null>: Execute the delete query that returns one or no result from the database. In case of more than one result found an exception will be thrown.executeDeleteOne(): Promise<RESULT>: Execute the delete query that returns one result from the database. If no result is returned by the database an exception will be thrown.executeDeleteMany(min?: number, max?: number): Promise<RESULT[]>: Execute the delete query that returns zero or many results from the database.
Aditionally, if you want to return the value of a single column, you can use returningOneColumn(column) instead of returning({...}).
Delete using other tables or views¶
Sometimes you want to include in the delete query other tables or views to process the delete instruction, you can add the using clause that is like a from clause in a select statement. This is supported by PostgreSQL, SQL Server, MariaDB, MySQL and Oracle (Oracle Database 23ai or newer).
const deleteACMECustomers = connection.deleteFrom(tCustomer)
.using(tCompany)
.where(tCustomer.companyId.equals(tCompany.id))
.and(tCompany.name.containsInsensitive('ACME'))
.executeDelete()
The executed query is:
The parameters are: [ 'ACME' ]
The result type is a promise with the information of the deleted rows:
Bulk delete¶
Sometimes you need to delete multiple rows in a single query, where each condition depends on different data. For these cases, you can map the constant values as a view and perform the deletion. This is supported by PostgreSQL, SQL Server, MariaDB and MySQL. MariaDB and MySQL drive it through their multi-table DELETE ... USING target, name form. On Oracle — even on Oracle 23ai, where deleteFrom.using(...) itself is accepted — combining a Values view with deleteFrom.using(...) would emit WITH name AS (VALUES …) DELETE … USING name, which the Oracle parser rejects with ORA-00928: SELECT keyword missing because it does not allow a WITH clause to precede a DELETE … USING statement; use a MERGE or a correlated subquery for the bulk-delete use case instead.
class VCustomerForDelete extends Values<DBConnection, 'customerForDelete'> {
firstName = this.column('string')
lastName = this.column('string')
}
const customerForDelete = Values.create(VCustomerForDelete, 'customerForDelete', [{
firstName: 'First Name',
lastName: 'Last Name'
}])
const deleteCustomer = connection.deleteFrom(tCustomer)
.using(customerForDelete)
.where(tCustomer.firstName.equals(customerForDelete.firstName))
.and(tCustomer.lastName.equals(customerForDelete.lastName))
.executeDelete()
The executed query is:
The parameters are: [ 'First Name', 'Last Name' ]
The result type is a promise with the information of the deleted rows: