コンテンツにスキップ

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{column = value}ペア

戻り値: Sqlizer

テーブルから不等価条件を作成。

local cond = sql.builder.not_eq({status = "closed"})
パラメータ説明
maptable{column = value}ペア

戻り値: Sqlizer

テーブルから小なり条件を作成。

local cond = sql.builder.lt({age = 18})
パラメータ説明
maptable{column = value}ペア

戻り値: Sqlizer

テーブルから以下条件を作成。

local cond = sql.builder.lte({price = 100})
パラメータ説明
maptable{column = value}ペア

戻り値: Sqlizer

テーブルから大なり条件を作成。

local cond = sql.builder.gt({score = 80})
パラメータ説明
maptable{column = value}ペア

戻り値: Sqlizer

テーブルから以上条件を作成。

local cond = sql.builder.gte({age = 21})
パラメータ説明
maptable{column = value}ペア

戻り値: Sqlizer

テーブルからLIKE条件を作成。

local cond = sql.builder.like({name = "john%"})
パラメータ説明
maptable{column = value}ペア

戻り値: Sqlizer

テーブルからNOT LIKE条件を作成。

local cond = sql.builder.not_like({email = "%@spam.com"})
パラメータ説明
maptable{column = value}ペア

戻り値: 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バインド引数(オプション、文字列使用時)

3つの形式をサポート:

  • 文字列: 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{column = value}ペア

戻り値: 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{column = value}ペア

戻り値: 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.getDatabase IDデータベース接続を取得
条件種別再試行可能
リソースIDが空errors.INVALIDno
権限拒否errors.PERMISSION_DENIEDno
リソースが見つからないerrors.NOT_FOUNDno
リソースがデータベースではないerrors.INVALIDno
無効なパラメータerrors.INVALIDno
SQL構文エラーerrors.INVALIDno
ステートメントがクローズ済みerrors.INVALIDno
トランザクションがアクティブでないerrors.INVALIDno
無効なセーブポイント名errors.INVALIDno
クエリ実行エラー様々様々

エラーの処理についてはエラー処理を参照。

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