⌘+k ctrl+k
1.4 (LTS)
搜索快捷键 cmd + k | ctrl + k
预处理语句

预编译语句(Prepared Statement)是一种参数化查询。查询语句通过问号(?)或美元符号($1)来标识查询参数。随后,可以将具体的值绑定到这些参数上,并使用这些参数执行预编译语句。单个查询可以预编译一次,并执行多次。

预编译语句的用途:

  • 在向函数提供参数时更加简便,同时避免字符串拼接带来的 SQL 注入攻击。
  • 加速那些使用不同参数多次执行的查询。

DuckDB 通过 C API 中的 duckdb_prepare 方法支持预编译语句。duckdb_bind 系列函数用于为后续通过 duckdb_execute_prepared 执行的预编译语句提供值。当我们使用完预编译语句后,可以使用 duckdb_destroy_prepare 方法进行清理。

示例

duckdb_prepared_statement stmt;
duckdb_result result;
if (duckdb_prepare(con, "INSERT INTO integers VALUES ($1, $2)", &stmt) == DuckDBError) {
    // handle error
}

duckdb_bind_int32(stmt, 1, 42); // the parameter index starts counting at 1!
duckdb_bind_int32(stmt, 2, 43);
// NULL as second parameter means no result set is requested
duckdb_execute_prepared(stmt, NULL);
duckdb_destroy_prepare(&stmt);

// we can also query result sets using prepared statements
if (duckdb_prepare(con, "SELECT * FROM integers WHERE i = ?", &stmt) == DuckDBError) {
    // handle error
}
duckdb_bind_int32(stmt, 1, 42);
duckdb_execute_prepared(stmt, &result);

// do something with result

// clean up
duckdb_destroy_result(&result);
duckdb_destroy_prepare(&stmt);

调用 duckdb_prepare 后,可以使用 duckdb_nparamsduckdb_param_type 检查预编译语句的参数。如果预编译失败,可以通过 duckdb_prepare_error 获取错误信息。

并不要求 duckdb_bind 系列函数的参数类型与预编译语句的参数类型完全匹配。值会根据需要自动转换。例如,对 DUCKDB_TYPE_INTEGER 类型的参数调用 duckdb_bind_int8 将会按预期工作。

警告:请不要使用预编译语句向 DuckDB 插入大量数据。建议改用 Appender

API参考概览

duckdb_state duckdb_prepare(duckdb_connection connection, const char *query, duckdb_prepared_statement *out_prepared_statement);
void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement);
const char *duckdb_prepare_error(duckdb_prepared_statement prepared_statement);
idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement);
const char *duckdb_parameter_name(duckdb_prepared_statement prepared_statement, idx_t index);
duckdb_type duckdb_param_type(duckdb_prepared_statement prepared_statement, idx_t param_idx);
duckdb_logical_type duckdb_param_logical_type(duckdb_prepared_statement prepared_statement, idx_t param_idx);
duckdb_state duckdb_clear_bindings(duckdb_prepared_statement prepared_statement);
duckdb_statement_type duckdb_prepared_statement_type(duckdb_prepared_statement statement);
idx_t duckdb_prepared_statement_column_count(duckdb_prepared_statement prepared_statement);
const char *duckdb_prepared_statement_column_name(duckdb_prepared_statement prepared_statement, idx_t col_idx);
duckdb_logical_type duckdb_prepared_statement_column_logical_type(duckdb_prepared_statement prepared_statement, idx_t col_idx);
duckdb_type duckdb_prepared_statement_column_type(duckdb_prepared_statement prepared_statement, idx_t col_idx);

duckdb_prepare

从查询创建预编译语句对象。

注意,在调用 duckdb_prepare 后,无论预编译是否成功,都应始终使用 duckdb_destroy_prepare 销毁预编译语句。

如果预编译失败,可以调用 duckdb_prepare_error 获取失败原因。

语法
duckdb_state duckdb_prepare(
  duckdb_connection connection,
  const char *query,
  duckdb_prepared_statement *out_prepared_statement
);
参数
  • connection:连接对象
  • query:要预编译的 SQL 查询
  • out_prepared_statement:生成的预编译语句对象
返回值

成功时返回 DuckDBSuccess,失败时返回 DuckDBError


duckdb_destroy_prepare

关闭预编译语句并释放为该语句分配的所有内存。

语法
void duckdb_destroy_prepare(
  duckdb_prepared_statement *prepared_statement
);
参数
  • prepared_statement:要销毁的预编译语句。


duckdb_prepare_error

返回与给定预编译语句关联的错误消息。如果预编译语句没有错误消息,则返回 nullptr

错误消息不应被手动释放。它会在调用 duckdb_destroy_prepare 时被释放。

语法
const char *duckdb_prepare_error(
  duckdb_prepared_statement prepared_statement
);
参数
  • prepared_statement:从中获取错误的预编译语句。
返回值

错误消息,如果没有则为 nullptr


duckdb_nparams

返回可提供给给定预编译语句的参数数量。

如果查询未成功预编译,则返回 0。

语法
idx_t duckdb_nparams(
  duckdb_prepared_statement prepared_statement
);
参数
  • prepared_statement:从中获取参数数量的预编译语句。


duckdb_parameter_name

返回用于标识参数的名称。返回的字符串应使用 duckdb_free 释放。

如果索引超出给定预编译语句的范围,则返回 NULL。

语法
const char *duckdb_parameter_name(
  duckdb_prepared_statement prepared_statement,
  idx_t index
);
参数
  • prepared_statement:要获取参数名称的预编译语句。


duckdb_param_type

返回给定索引处参数的参数类型。

如果参数索引超出范围或语句未成功预编译,则返回 DUCKDB_TYPE_INVALID

语法
duckdb_type duckdb_param_type(
  duckdb_prepared_statement prepared_statement,
  idx_t param_idx
);
参数
  • prepared_statement:预编译语句。
  • param_idx:参数索引。
返回值

参数类型


duckdb_param_logical_type

返回给定索引处参数的逻辑类型。

如果参数索引超出范围或语句未成功预编译,则返回 nullptr

此调用的返回类型应使用 duckdb_destroy_logical_type 销毁。

语法
duckdb_logical_type duckdb_param_logical_type(
  duckdb_prepared_statement prepared_statement,
  idx_t param_idx
);
参数
  • prepared_statement:预编译语句。
  • param_idx:参数索引。
返回值

参数的逻辑类型


duckdb_clear_bindings

清除绑定到预编译语句的参数。

语法
duckdb_state duckdb_clear_bindings(
  duckdb_prepared_statement prepared_statement
);


duckdb_prepared_statement_type

返回要执行的语句的类型

语法
duckdb_statement_type duckdb_prepared_statement_type(
  duckdb_prepared_statement statement
);
参数
  • statement:预编译语句。
返回值

duckdb_statement_type 值或 DUCKDB_STATEMENT_TYPE_INVALID


duckdb_prepared_statement_column_count

返回预编译语句结果中存在的列数。如果任何列类型无效,结果将为 1。

语法
idx_t duckdb_prepared_statement_column_count(
  duckdb_prepared_statement prepared_statement
);
参数
  • prepared_statement:预编译语句。
返回值

预编译语句结果中存在的列数。


duckdb_prepared_statement_column_name

返回预编译语句结果中指定列的名称。返回的字符串应使用 duckdb_free 释放。

如果列超出范围,返回 nullptr

语法
const char *duckdb_prepared_statement_column_name(
  duckdb_prepared_statement prepared_statement,
  idx_t col_idx
);
参数
  • prepared_statement:预编译语句。
  • col_idx:列索引。
返回值

指定列的列名。


duckdb_prepared_statement_column_logical_type

返回预编译语句结果中指定列的列类型。

如果列超出范围,返回 DUCKDB_TYPE_INVALID。此调用的返回类型应使用 duckdb_destroy_logical_type 销毁。

语法
duckdb_logical_type duckdb_prepared_statement_column_logical_type(
  duckdb_prepared_statement prepared_statement,
  idx_t col_idx
);
参数
  • prepared_statement:要从中获取列类型的预编译语句。
  • col_idx:列索引。
返回值

指定列的逻辑类型。


duckdb_prepared_statement_column_type

返回预编译语句结果中指定列的列类型。

如果列超出范围,则返回 DUCKDB_TYPE_INVALID

语法
duckdb_type duckdb_prepared_statement_column_type(
  duckdb_prepared_statement prepared_statement,
  idx_t col_idx
);
参数
  • prepared_statement:要从中获取列类型的预编译语句。
  • col_idx:列索引。
返回值

指定列的类型。


© 2025 DuckDB 基金会,阿姆斯特丹,荷兰
行为准则 商标使用指南