跳转到内容

SQL 数据库

对 PostgreSQL、MySQL 和 SQLite 数据库执行 SQL 查询。支持参数化查询、事务、预处理语句和流式查询构建器。

数据库配置请参阅 数据库

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()
参数类型描述
idstring资源 ID(例如 “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

创建用于 where/having 子句的原始 SQL 表达式。

local expr = sql.builder.expr("score BETWEEN ? AND ?", 80, 90)
参数类型描述
sqlstring带 ? 占位符的 SQL 表达式
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})
})
参数类型描述
conditionstableSqlizer 或表条件数组

返回: Sqlizer

用 OR 组合多个条件。

local cond = sql.builder.or_({
sql.builder.eq({status = "pending"}),
sql.builder.eq({status = "active"})
})
参数类型描述
conditionstableSqlizer 或表条件数组

返回: 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})
参数类型描述
sqlstring带 ? 占位符的 SQL 查询
paramstable绑定参数数组(可选)

返回: table[], error

执行 INSERT/UPDATE/DELETE 查询。

local result, err = db:execute("INSERT INTO users (name) VALUES (?)", {"alice"})
参数类型描述
sqlstring带 ? 占位符的 SQL 语句
paramstable绑定参数数组(可选)

返回: table, error

返回包含以下字段的表:

  • last_insert_id - 最后插入的 ID
  • rows_affected - 受影响的行数

创建可重复执行的预处理语句。

local stmt, err = db:prepare("SELECT * FROM users WHERE id = ?")
参数类型描述
sqlstring带 ? 占位符的 SQL

返回: 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_time_closed - 因空闲超时而关闭的连接数
  • max_lifetime_closed - 因达到最大生命周期而关闭的连接数

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})
参数类型描述
sqlstring带 ? 占位符的 SQL 查询
paramstable绑定参数数组(可选)

返回: table[], error

在事务中执行 INSERT/UPDATE/DELETE。

local result, err = tx:execute("INSERT INTO users (name) VALUES (?)", {"alice"})
参数类型描述
sqlstring带 ? 占位符的 SQL 语句
paramstable绑定参数数组(可选)

返回: table, error

返回包含以下字段的表:

  • last_insert_id - 最后插入的 ID
  • rows_affected - 受影响的行数

在事务中创建预处理语句。

local stmt, err = tx:prepare("SELECT * FROM users WHERE id = ?")
参数类型描述
sqlstring带 ? 占位符的 SQL

返回: 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

用于构建 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")
参数类型描述
joinstring带 ? 占位符的 JOIN 子句
args…any绑定参数(可选)

返回: SelectBuilder

添加 LEFT JOIN 子句。

local query = sql.builder.select("*")
:from("users")
:left_join("orders ON orders.user_id = users.id")
参数类型描述
joinstring带 ? 占位符的 JOIN 子句
args…any绑定参数(可选)

返回: SelectBuilder

添加 RIGHT JOIN 子句。

local query = sql.builder.select("*")
:from("users")
:right_join("orders ON orders.user_id = users.id")
参数类型描述
joinstring带 ? 占位符的 JOIN 子句
args…any绑定参数(可选)

返回: SelectBuilder

添加 INNER JOIN 子句。

local query = sql.builder.select("*")
:from("users")
:inner_join("orders ON orders.user_id = users.id")
参数类型描述
joinstring带 ? 占位符的 JOIN 子句
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")
参数类型描述
sqlstring带 ? 占位符的 SQL 后缀
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

用于构建 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")
参数类型描述
sqlstring带 ? 占位符的 SQL 前缀
args…any绑定参数(可选)

返回: InsertBuilder

添加 SQL 后缀。

local query = sql.builder.insert("users")
:columns("name")
:values("alice")
:suffix("RETURNING id")
参数类型描述
sqlstring带 ? 占位符的 SQL 后缀
args…any绑定参数(可选)

返回: InsertBuilder

添加 INSERT 选项。

local query = sql.builder.insert("users")
:options("DELAYED", "IGNORE")
参数类型描述
options…stringINSERT 选项

返回: 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

用于构建 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")
参数类型描述
sqlstring带 ? 占位符的 SQL 后缀
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

用于构建 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")
参数类型描述
sqlstring带 ? 占位符的 SQL 后缀
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.get数据库 ID获取数据库连接
条件类型可重试
资源 ID 为空errors.INVALID
权限被拒绝errors.PERMISSION_DENIED
资源未找到errors.NOT_FOUND
资源不是数据库errors.INVALID
参数无效errors.INVALID
SQL 语法错误errors.INVALID
语句已关闭errors.INVALID
事务未激活errors.INVALID
保存点名称无效errors.INVALID
查询执行错误各种各种

错误处理请参阅 错误处理

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()