Перейти к содержимому

База данных SQL

Выполнение SQL-запросов к базам данных PostgreSQL, MySQL и SQLite. Поддержка параметризованных запросов, транзакций, подготовленных выражений и fluent-конструктора запросов.

Настройку базы данных см. в Database.

local sql = require("sql")

Получить соединение с базой данных из реестра ресурсов:

local db, err = sql.get("app.db:main")
if err then
return nil, err
end
local rows = db:query("SELECT * FROM users WHERE active = ?", {1})
db:release()
ПараметрТипОписание
idstringID ресурса (например, “app.db:main”)

Возвращает: DB, error

Соединения автоматически возвращаются в пул при выходе из функции, но рекомендуется явно вызывать `db:release()` для длительных операций. Плейсхолдеры передаются драйверу базы данных без изменений; среда выполнения их не переписывает. SQLite и MySQL используют `?`, PostgreSQL использует `$1, $2` — записывайте их в форме, ожидаемой вашим драйвером. В примерах ниже используется `?` (SQLite/MySQL). Для запросов, рассчитанных на несколько движков, стройте их с помощью конструктора запросов и задавайте `placeholder_format` нужного диалекта.
sql.type.POSTGRES -- "postgres"
sql.type.MYSQL -- "mysql"
sql.type.SQLITE -- "sqlite"
sql.type.UNKNOWN -- "unknown"
sql.isolation.DEFAULT -- "default"
sql.isolation.READ_UNCOMMITTED -- "read_uncommitted"
sql.isolation.READ_COMMITTED -- "read_committed"
sql.isolation.WRITE_COMMITTED -- "write_committed"
sql.isolation.REPEATABLE_READ -- "repeatable_read"
sql.isolation.SERIALIZABLE -- "serializable"
local insert = sql.builder.insert("users")
:columns("name", "email")
:values("alice", sql.NULL)
local value = sql.as.int(42)

Возвращает: userdata

Приведение значения к SQL-типу float.

local value = sql.as.float(19.99)

Возвращает: userdata

Приведение значения к SQL-типу text.

local value = sql.as.text("hello")

Возвращает: userdata

Приведение значения к SQL-типу binary.

local value = sql.as.binary("binary data")

Возвращает: userdata

Возвращает маркер SQL NULL.

local value = sql.as.null()

Возвращает: userdata

local query = sql.builder.select("id", "name")
:from("users")
:where({active = 1})
ПараметрТипОписание
columns…stringИмена колонок (опционально)

Возвращает: SelectBuilder

Создаёт конструктор INSERT-запроса.

local query = sql.builder.insert("users")
:columns("name", "email")
:values("alice", "alice@example.com")
ПараметрТипОписание
tablestringИмя таблицы (опционально)

Возвращает: InsertBuilder

Создаёт конструктор UPDATE-запроса.

local query = sql.builder.update("users")
:set("status", "active")
:where({id = 123})
ПараметрТипОписание
tablestringИмя таблицы (опционально)

Возвращает: UpdateBuilder

Создаёт конструктор DELETE-запроса.

local query = sql.builder.delete("users")
:where({active = 0})
:limit(100)
ПараметрТипОписание
tablestringИмя таблицы (опционально)

Возвращает: DeleteBuilder

Создаёт сырое SQL-выражение для использования в where/having.

local expr = sql.builder.expr("score BETWEEN ? AND ?", 80, 90)
ПараметрТипОписание
sqlstringSQL-выражение с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: Sqlizer

Создаёт условие равенства из таблицы.

local cond = sql.builder.eq({active = 1, status = "open"})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: Sqlizer

Создаёт условие неравенства из таблицы.

local cond = sql.builder.not_eq({status = "closed"})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: Sqlizer

Создаёт условие «меньше» из таблицы.

local cond = sql.builder.lt({age = 18})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: Sqlizer

Создаёт условие «меньше или равно» из таблицы.

local cond = sql.builder.lte({price = 100})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: Sqlizer

Создаёт условие «больше» из таблицы.

local cond = sql.builder.gt({score = 80})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: Sqlizer

Создаёт условие «больше или равно» из таблицы.

local cond = sql.builder.gte({age = 21})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: Sqlizer

Создаёт условие LIKE из таблицы.

local cond = sql.builder.like({name = "john%"})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: Sqlizer

Создаёт условие NOT LIKE из таблицы.

local cond = sql.builder.not_like({email = "%@spam.com"})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: Sqlizer

Объединяет несколько условий через AND.

local cond = sql.builder.and_({
sql.builder.eq({active = 1}),
sql.builder.gt({score = 80})
})
ПараметрТипОписание
conditionstableМассив Sqlizer или табличных условий

Возвращает: Sqlizer

Объединяет несколько условий через OR.

local cond = sql.builder.or_({
sql.builder.eq({status = "pending"}),
sql.builder.eq({status = "active"})
})
ПараметрТипОписание
conditionstableМассив Sqlizer или табличных условий

Возвращает: Sqlizer

Формат плейсхолдеров ? (по умолчанию). Доступен как алиас sql.builder.default_placeholder.

local query = sql.builder.select("*")
:from("users")
:placeholder_format(sql.builder.question)

Формат плейсхолдеров $1, $2, …

local query = sql.builder.select("*")
:from("users")
:placeholder_format(sql.builder.dollar)

Формат плейсхолдеров @p1, @p2, ... (стиль SQL Server). Передаётся в placeholder_format как форматы выше.

Формат плейсхолдеров :1, :2, .... Передаётся в placeholder_format как форматы выше.

Дескриптор соединения, возвращаемый sql.get().

Возвращает константу типа базы данных.

local dbtype, err = db:type()

Возвращает: string, error

Выполняет SELECT-запрос и возвращает строки.

local rows, err = db:query("SELECT id, name FROM users WHERE active = ?", {1})
ПараметрТипОписание
sqlstringSQL-запрос с плейсхолдерами ?
paramstableМассив параметров привязки (опционально)

Возвращает: table[], error

Выполняет INSERT/UPDATE/DELETE-запрос.

local result, err = db:execute("INSERT INTO users (name) VALUES (?)", {"alice"})
ПараметрТипОписание
sqlstringSQL-выражение с плейсхолдерами ?
paramstableМассив параметров привязки (опционально)

Возвращает: table, error

Возвращаемая таблица содержит поля:

  • last_insert_id — ID последней вставленной записи
  • rows_affected — количество затронутых строк

Создаёт подготовленное выражение для многократного выполнения.

local stmt, err = db:prepare("SELECT * FROM users WHERE id = ?")
ПараметрТипОписание
sqlstringSQL с плейсхолдерами ?

Возвращает: Statement, error

Начинает транзакцию базы данных.

local tx, err = db:begin({
isolation = sql.isolation.SERIALIZABLE,
read_only = false
})
ПараметрТипОписание
optionstableОпции транзакции (опционально)

Поля таблицы опций:

  • isolation — уровень изоляции из sql.isolation.* (по умолчанию: DEFAULT)
  • read_only — флаг транзакции только для чтения (по умолчанию: false)

Возвращает: Transaction, error

Возвращает ресурс базы данных в пул.

local ok, err = db:release()

Возвращает: boolean, error

Возвращает статистику пула соединений.

local stats, err = db:stats()

Возвращает: table, error

Возвращаемая таблица содержит поля:

  • max_open_connections — максимум открытых соединений
  • open_connections — текущих открытых соединений
  • in_use — соединений в использовании
  • idle — простаивающих соединений в пуле
  • wait_count — всего ожиданий соединения
  • wait_duration — общее время ожидания
  • max_idle_closed — соединений закрыто из-за max idle
  • max_idle_time_closed — соединений закрыто по таймауту простоя
  • max_lifetime_closed — соединений закрыто по max lifetime

Подготовленное выражение, возвращаемое db:prepare().

Выполняет подготовленное выражение как SELECT.

local rows, err = stmt:query({123})
ПараметрТипОписание
paramstableМассив параметров привязки (опционально)

Возвращает: table[], error

Выполняет подготовленное выражение как INSERT/UPDATE/DELETE.

local result, err = stmt:execute({"alice"})
ПараметрТипОписание
paramstableМассив параметров привязки (опционально)

Возвращает: table, error

Возвращаемая таблица содержит поля:

  • last_insert_id — ID последней вставленной записи
  • rows_affected — количество затронутых строк

Закрывает подготовленное выражение.

local ok, err = stmt:close()

Возвращает: boolean, error

Транзакция базы данных, возвращаемая db:begin().

Возвращает константу типа базы данных.

local dbtype, err = tx:db_type()

Возвращает: string, error

Выполняет SELECT-запрос внутри транзакции.

local rows, err = tx:query("SELECT id, name FROM users WHERE active = ?", {1})
ПараметрТипОписание
sqlstringSQL-запрос с плейсхолдерами ?
paramstableМассив параметров привязки (опционально)

Возвращает: table[], error

Выполняет INSERT/UPDATE/DELETE внутри транзакции.

local result, err = tx:execute("INSERT INTO users (name) VALUES (?)", {"alice"})
ПараметрТипОписание
sqlstringSQL-выражение с плейсхолдерами ?
paramstableМассив параметров привязки (опционально)

Возвращает: table, error

Возвращаемая таблица содержит поля:

  • last_insert_id — ID последней вставленной записи
  • rows_affected — количество затронутых строк

Создаёт подготовленное выражение внутри транзакции.

local stmt, err = tx:prepare("SELECT * FROM users WHERE id = ?")
ПараметрТипОписание
sqlstringSQL с плейсхолдерами ?

Возвращает: Statement, error

Фиксирует транзакцию.

local ok, err = tx:commit()

Возвращает: boolean, error

Откатывает транзакцию.

local ok, err = tx:rollback()

Возвращает: boolean, error

Создаёт именованную точку сохранения внутри транзакции.

local ok, err = tx:savepoint("sp1")
ПараметрТипОписание
namestringИмя точки сохранения (только буквы, цифры и подчёркивание)

Возвращает: boolean, error

Откатывает к именованной точке сохранения.

local ok, err = tx:rollback_to("sp1")
ПараметрТипОписание
namestringИмя точки сохранения

Возвращает: boolean, error

Освобождает точку сохранения.

local ok, err = tx:release("sp1")
ПараметрТипОписание
namestringИмя точки сохранения

Возвращает: boolean, error

Fluent-интерфейс для построения SELECT-запросов.

Устанавливает FROM-часть.

local query = sql.builder.select("id", "name"):from("users")
ПараметрТипОписание
tablestringИмя таблицы

Возвращает: SelectBuilder

Добавляет JOIN-часть.

local query = sql.builder.select("*")
:from("users")
:join("orders ON orders.user_id = users.id")
ПараметрТипОписание
joinstringJOIN-часть с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: SelectBuilder

Добавляет LEFT JOIN-часть.

local query = sql.builder.select("*")
:from("users")
:left_join("orders ON orders.user_id = users.id")
ПараметрТипОписание
joinstringJOIN-часть с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: SelectBuilder

Добавляет RIGHT JOIN-часть.

local query = sql.builder.select("*")
:from("users")
:right_join("orders ON orders.user_id = users.id")
ПараметрТипОписание
joinstringJOIN-часть с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: SelectBuilder

Добавляет INNER JOIN-часть.

local query = sql.builder.select("*")
:from("users")
:inner_join("orders ON orders.user_id = users.id")
ПараметрТипОписание
joinstringJOIN-часть с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: SelectBuilder

Добавляет WHERE-условие.

local query = sql.builder.select("*")
:from("users")
:where({active = 1})
ПараметрТипОписание
conditionstring|table|SqlizerWHERE-условие
args…anyАргументы привязки (опционально, при использовании строки)

Поддерживает три формата:

  • Строка: where("status = ?", "active")
  • Таблица: where({status = "active"})
  • Sqlizer: where(sql.builder.gt({score = 80}))

Возвращает: SelectBuilder

Добавляет ORDER BY-часть.

local query = sql.builder.select("*")
:from("users")
:order_by("name ASC", "created_at DESC")
ПараметрТипОписание
columns…stringИмена колонок с опциональным ASC/DESC

Возвращает: SelectBuilder

Добавляет GROUP BY-часть.

local query = sql.builder.select("status", "COUNT(*)")
:from("users")
:group_by("status")
ПараметрТипОписание
columns…stringИмена колонок

Возвращает: SelectBuilder

Добавляет HAVING-условие.

local query = sql.builder.select("status", "COUNT(*) as cnt")
:from("users")
:group_by("status")
:having(sql.builder.gt({cnt = 10}))
ПараметрТипОписание
conditionstring|table|SqlizerHAVING-условие
args…anyАргументы привязки (опционально, при использовании строки)

Возвращает: SelectBuilder

Устанавливает LIMIT.

local query = sql.builder.select("*")
:from("users")
:limit(10)
ПараметрТипОписание
nintegerЗначение лимита

Возвращает: SelectBuilder

Устанавливает OFFSET.

local query = sql.builder.select("*")
:from("users")
:offset(20)
ПараметрТипОписание
nintegerЗначение смещения

Возвращает: SelectBuilder

Добавляет колонки в SELECT.

local query = sql.builder.select():columns("id", "name", "email")
ПараметрТипОписание
columns…stringИмена колонок

Возвращает: SelectBuilder

Добавляет модификатор DISTINCT.

local query = sql.builder.select("status")
:from("users")
:distinct()

Возвращает: SelectBuilder

Добавляет SQL-суффикс.

local query = sql.builder.select("*")
:from("users")
:suffix("FOR UPDATE")
ПараметрТипОписание
sqlstringSQL-суффикс с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: SelectBuilder

Устанавливает формат плейсхолдеров.

local query = sql.builder.select("*")
:from("users")
:placeholder_format(sql.builder.dollar)
ПараметрТипОписание
formatuserdataФормат плейсхолдеров (sql.builder.*)

Возвращает: SelectBuilder

Генерирует SQL-строку и аргументы привязки.

local sql_str, args = query:to_sql()

Возвращает: string, table

Создаёт исполнитель для запроса.

local executor = query:run_with(db)
local rows, err = executor:query()
ПараметрТипОписание
dbDB|TransactionДескриптор базы данных или транзакции

Возвращает: QueryExecutor

Fluent-интерфейс для построения INSERT-запросов.

Устанавливает имя таблицы.

local query = sql.builder.insert():into("users")
ПараметрТипОписание
tablestringИмя таблицы

Возвращает: InsertBuilder

Устанавливает имена колонок.

local query = sql.builder.insert("users"):columns("name", "email")
ПараметрТипОписание
columns…stringИмена колонок

Возвращает: InsertBuilder

Добавляет значения строки.

local query = sql.builder.insert("users")
:columns("name", "email")
:values("alice", "alice@example.com")
ПараметрТипОписание
values…anyЗначения строки

Возвращает: InsertBuilder

Устанавливает колонки и значения из таблицы.

local query = sql.builder.insert("users")
:set_map({name = "alice", email = "alice@example.com"})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: InsertBuilder

Вставляет из SELECT-запроса.

local select_query = sql.builder.select("name", "email"):from("temp_users")
local query = sql.builder.insert("users")
:columns("name", "email")
:select(select_query)
ПараметрТипОписание
querySelectBuilderSELECT-запрос

Возвращает: InsertBuilder

Добавляет SQL-префикс.

local query = sql.builder.insert("users")
:prefix("INSERT IGNORE INTO")
ПараметрТипОписание
sqlstringSQL-префикс с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: InsertBuilder

Добавляет SQL-суффикс.

local query = sql.builder.insert("users")
:columns("name")
:values("alice")
:suffix("RETURNING id")
ПараметрТипОписание
sqlstringSQL-суффикс с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: InsertBuilder

Добавляет опции INSERT.

local query = sql.builder.insert("users")
:options("DELAYED", "IGNORE")
ПараметрТипОписание
options…stringОпции INSERT

Возвращает: InsertBuilder

Устанавливает формат плейсхолдеров.

local query = sql.builder.insert("users")
:placeholder_format(sql.builder.dollar)
ПараметрТипОписание
formatuserdataФормат плейсхолдеров (sql.builder.*)

Возвращает: InsertBuilder

Генерирует SQL-строку и аргументы привязки.

local sql_str, args = query:to_sql()

Возвращает: string, table

Создаёт исполнитель для запроса.

local executor = query:run_with(db)
local result, err = executor:exec()
ПараметрТипОписание
dbDB|TransactionДескриптор базы данных или транзакции

Возвращает: QueryExecutor

Fluent-интерфейс для построения UPDATE-запросов.

Устанавливает имя таблицы.

local query = sql.builder.update():table("users")
ПараметрТипОписание
tablestringИмя таблицы

Возвращает: UpdateBuilder

Устанавливает значение колонки.

local query = sql.builder.update("users")
:set("status", "active")
:set("updated_at", sql.builder.expr("NOW()"))
ПараметрТипОписание
columnstringИмя колонки
valueanyЗначение колонки

Возвращает: UpdateBuilder

Устанавливает несколько колонок из таблицы.

local query = sql.builder.update("users")
:set_map({status = "active", updated_at = sql.builder.expr("NOW()")})
ПараметрТипОписание
maptableПары {колонка = значение}

Возвращает: UpdateBuilder

Добавляет WHERE-условие.

local query = sql.builder.update("users")
:set("status", "active")
:where({id = 123})
ПараметрТипОписание
conditionstring|table|SqlizerWHERE-условие
args…anyАргументы привязки (опционально, при использовании строки)

Возвращает: UpdateBuilder

Добавляет ORDER BY-часть.

local query = sql.builder.update("users")
:set("rank", 1)
:order_by("score DESC")
ПараметрТипОписание
columns…stringИмена колонок с опциональным ASC/DESC

Возвращает: UpdateBuilder

Устанавливает LIMIT.

local query = sql.builder.update("users")
:set("status", "active")
:limit(10)
ПараметрТипОписание
nintegerЗначение лимита

Возвращает: UpdateBuilder

Устанавливает OFFSET.

local query = sql.builder.update("users")
:set("status", "active")
:offset(5)
ПараметрТипОписание
nintegerЗначение смещения

Возвращает: UpdateBuilder

Добавляет SQL-суффикс.

local query = sql.builder.update("users")
:set("status", "active")
:suffix("RETURNING id")
ПараметрТипОписание
sqlstringSQL-суффикс с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: UpdateBuilder

Добавляет FROM-часть.

local query = sql.builder.update("users")
:set("status", "active")
:from("other_table")
ПараметрТипОписание
tablestringИмя таблицы

Возвращает: UpdateBuilder

Обновляет из SELECT-запроса.

local select_query = sql.builder.select("*"):from("temp_users")
local query = sql.builder.update("users")
:set("status", "active")
:from_select(select_query, "t")
ПараметрТипОписание
querySelectBuilderSELECT-запрос
aliasstringАлиас таблицы

Возвращает: UpdateBuilder

Устанавливает формат плейсхолдеров.

local query = sql.builder.update("users")
:placeholder_format(sql.builder.dollar)
ПараметрТипОписание
formatuserdataФормат плейсхолдеров (sql.builder.*)

Возвращает: UpdateBuilder

Генерирует SQL-строку и аргументы привязки.

local sql_str, args = query:to_sql()

Возвращает: string, table

Создаёт исполнитель для запроса.

local executor = query:run_with(db)
local result, err = executor:exec()
ПараметрТипОписание
dbDB|TransactionДескриптор базы данных или транзакции

Возвращает: QueryExecutor

Fluent-интерфейс для построения DELETE-запросов.

Устанавливает имя таблицы.

local query = sql.builder.delete():from("users")
ПараметрТипОписание
tablestringИмя таблицы

Возвращает: DeleteBuilder

Добавляет WHERE-условие.

local query = sql.builder.delete("users")
:where({active = 0})
ПараметрТипОписание
conditionstring|table|SqlizerWHERE-условие
args…anyАргументы привязки (опционально, при использовании строки)

Возвращает: DeleteBuilder

Добавляет ORDER BY-часть.

local query = sql.builder.delete("users")
:where({active = 0})
:order_by("created_at ASC")
ПараметрТипОписание
columns…stringИмена колонок с опциональным ASC/DESC

Возвращает: DeleteBuilder

Устанавливает LIMIT.

local query = sql.builder.delete("users")
:where({active = 0})
:limit(100)
ПараметрТипОписание
nintegerЗначение лимита

Возвращает: DeleteBuilder

Устанавливает OFFSET.

local query = sql.builder.delete("users")
:where({active = 0})
:offset(10)
ПараметрТипОписание
nintegerЗначение смещения

Возвращает: DeleteBuilder

Добавляет SQL-суффикс.

local query = sql.builder.delete("users")
:where({active = 0})
:suffix("RETURNING id")
ПараметрТипОписание
sqlstringSQL-суффикс с плейсхолдерами ?
args…anyАргументы привязки (опционально)

Возвращает: DeleteBuilder

Устанавливает формат плейсхолдеров.

local query = sql.builder.delete("users")
:placeholder_format(sql.builder.dollar)
ПараметрТипОписание
formatuserdataФормат плейсхолдеров (sql.builder.*)

Возвращает: DeleteBuilder

Генерирует SQL-строку и аргументы привязки.

local sql_str, args = query:to_sql()

Возвращает: string, table

Создаёт исполнитель для запроса.

local executor = query:run_with(db)
local result, err = executor:exec()
ПараметрТипОписание
dbDB|TransactionДескриптор базы данных или транзакции

Возвращает: QueryExecutor

Исполнитель запросов для запросов, построенных конструктором.

Выполняет запрос и возвращает строки (для SELECT).

local rows, err = executor:query()

Возвращает: table[], error

Выполняет запрос и возвращает результат (для INSERT/UPDATE/DELETE).

local result, err = executor:exec()

Возвращает: table, error

Возвращаемая таблица содержит поля:

  • last_insert_id — ID последней вставленной записи
  • rows_affected — количество затронутых строк

Возвращает сгенерированный SQL и аргументы без выполнения.

local sql_str, args = executor:to_sql()

Возвращает: string, table

Доступ к базе данных подчиняется вычислению политики безопасности.

ДействиеРесурсОписание
db.getID базы данныхПолучить соединение с базой данных
УсловиеKindПовторяемо
Пустой ID ресурсаerrors.INVALIDнет
Доступ запрещёнerrors.PERMISSION_DENIEDнет
Ресурс не найденerrors.NOT_FOUNDнет
Ресурс не является базой данныхerrors.INVALIDнет
Некорректные параметрыerrors.INVALIDнет
Синтаксическая ошибка SQLerrors.INVALIDнет
Statement закрытerrors.INVALIDнет
Транзакция не активнаerrors.INVALIDнет
Некорректное имя точки сохраненияerrors.INVALIDнет
Ошибка выполнения запросаvariesvaries

См. Обработка ошибок для работы с ошибками.

local sql = require("sql")
-- Получить соединение с базой данных
local db, err = sql.get("app.db:main")
if err then error(err) end
-- Проверить тип базы данных
local dbtype, _ = db:type()
print("Database type:", dbtype)
-- Прямой запрос
local users, err = db:query("SELECT id, name FROM users WHERE active = ?", {1})
if err then error(err) end
for _, user in ipairs(users) do
print(user.id, user.name)
end
-- Паттерн конструктора
local query = sql.builder.select("u.id", "u.name", "COUNT(o.id) as order_count")
:from("users u")
:left_join("orders o ON o.user_id = u.id")
:where(sql.builder.and_({
sql.builder.eq({["u.active"] = 1}),
sql.builder.gte({["u.score"] = 80})
}))
:group_by("u.id", "u.name")
:having(sql.builder.gt({["COUNT(o.id)"] = 0}))
:order_by("order_count DESC")
:limit(10)
local executor = query:run_with(db)
local results, err = executor:query()
if err then error(err) end
-- Транзакция с точками сохранения
local tx, err = db:begin({isolation = sql.isolation.SERIALIZABLE})
if err then error(err) end
local _, err = tx:execute("INSERT INTO users (name) VALUES (?)", {"alice"})
if err then
tx:rollback()
error(err)
end
tx:savepoint("sp1")
local _, err = tx:execute("UPDATE users SET status = ? WHERE id = ?", {"active", 1})
if err then
tx:rollback_to("sp1")
else
tx:release("sp1")
end
local ok, err = tx:commit()
if err then error(err) end
-- Подготовленные выражения
local stmt, err = db:prepare("INSERT INTO logs (message, level) VALUES (?, ?)")
if err then error(err) end
for i = 1, 100 do
local _, err = stmt:execute({"log message " .. i, "info"})
if err then
stmt:close()
error(err)
end
end
stmt:close()
-- NULL и типизированные значения
local insert = sql.builder.insert("products")
:columns("name", "price", "description")
:values("Widget", sql.as.float(19.99), sql.NULL)
local executor = insert:run_with(db)
local result, err = executor:exec()
if err then error(err) end
print("Inserted ID:", result.last_insert_id)
db:release()