duckdb_query
方法允许从 C 在 DuckDB 中运行 SQL 查询。此方法接受两个参数:一个 (null 结尾) SQL 查询字符串和一个 duckdb_result
结果指针。如果应用程序对结果集不感兴趣或者查询不产生任何结果,则结果指针可以为 NULL
。在使用完结果后,应使用 duckdb_destroy_result
方法清理结果。
可以使用多种方法从 duckdb_result
对象中提取元素。 duckdb_column_count
可用于提取列数。 duckdb_column_name
和 duckdb_column_type
可用于提取单个列的名称和类型。
示例
duckdb_state state;
duckdb_result result;
// create a table
state = duckdb_query(con, "CREATE TABLE integers (i INTEGER, j INTEGER);", NULL);
if (state == DuckDBError) {
// handle error
}
// insert three rows into the table
state = duckdb_query(con, "INSERT INTO integers VALUES (3, 4), (5, 6), (7, NULL);", NULL);
if (state == DuckDBError) {
// handle error
}
// query rows again
state = duckdb_query(con, "SELECT * FROM integers", &result);
if (state == DuckDBError) {
// handle error
}
// handle the result
// ...
// destroy the result after we are done with it
duckdb_destroy_result(&result);
值提取
可以使用 duckdb_fetch_chunk
函数或 duckdb_value
便利函数提取值。 duckdb_fetch_chunk
函数直接以 DuckDB 的原生数组格式将数据块传递给您,因此速度非常快。 duckdb_value
函数执行边界和类型检查,并将自动将值强制转换为所需的类型。这使得它们更方便且更易于使用,但代价是速度较慢。
有关更多信息,请参见类型页面。
为了获得最佳性能,请使用
duckdb_fetch_chunk
从查询结果中提取数据。duckdb_value
函数执行内部类型检查、边界检查和强制转换,这使其速度较慢。
duckdb_fetch_chunk
以下是一个端到端示例,使用 duckdb_fetch_chunk
函数将上述结果打印为 CSV 格式。请注意,该函数不是通用的:我们确实需要确切地知道结果列的类型是什么。
duckdb_database db;
duckdb_connection con;
duckdb_open(nullptr, &db);
duckdb_connect(db, &con);
duckdb_result res;
duckdb_query(con, "CREATE TABLE integers (i INTEGER, j INTEGER);", NULL);
duckdb_query(con, "INSERT INTO integers VALUES (3, 4), (5, 6), (7, NULL);", NULL);
duckdb_query(con, "SELECT * FROM integers;", &res);
// iterate until result is exhausted
while (true) {
duckdb_data_chunk result = duckdb_fetch_chunk(res);
if (!result) {
// result is exhausted
break;
}
// get the number of rows from the data chunk
idx_t row_count = duckdb_data_chunk_get_size(result);
// get the first column
duckdb_vector col1 = duckdb_data_chunk_get_vector(result, 0);
int32_t *col1_data = (int32_t *) duckdb_vector_get_data(col1);
uint64_t *col1_validity = duckdb_vector_get_validity(col1);
// get the second column
duckdb_vector col2 = duckdb_data_chunk_get_vector(result, 1);
int32_t *col2_data = (int32_t *) duckdb_vector_get_data(col2);
uint64_t *col2_validity = duckdb_vector_get_validity(col2);
// iterate over the rows
for (idx_t row = 0; row < row_count; row++) {
if (duckdb_validity_row_is_valid(col1_validity, row)) {
printf("%d", col1_data[row]);
} else {
printf("NULL");
}
printf(",");
if (duckdb_validity_row_is_valid(col2_validity, row)) {
printf("%d", col2_data[row]);
} else {
printf("NULL");
}
printf("\n");
}
duckdb_destroy_data_chunk(&result);
}
// clean-up
duckdb_destroy_result(&res);
duckdb_disconnect(&con);
duckdb_close(&db);
这会打印以下结果
3,4
5,6
7,NULL
duckdb_value
已弃用
duckdb_value
函数已弃用,计划在未来的版本中删除。
以下是一个示例,使用 duckdb_value_varchar
函数将上述结果打印为 CSV 格式。请注意,该函数是通用的:我们不需要了解单个结果列的类型。
// print the above result to CSV format using `duckdb_value_varchar`
idx_t row_count = duckdb_row_count(&result);
idx_t column_count = duckdb_column_count(&result);
for (idx_t row = 0; row < row_count; row++) {
for (idx_t col = 0; col < column_count; col++) {
if (col > 0) printf(",");
auto str_val = duckdb_value_varchar(&result, col, row);
printf("%s", str_val);
duckdb_free(str_val);
}
printf("\n");
}
API参考概览
duckdb_state duckdb_query(duckdb_connection connection, const char *query, duckdb_result *out_result);
void duckdb_destroy_result(duckdb_result *result);
const char *duckdb_column_name(duckdb_result *result, idx_t col);
duckdb_type duckdb_column_type(duckdb_result *result, idx_t col);
duckdb_statement_type duckdb_result_statement_type(duckdb_result result);
duckdb_logical_type duckdb_column_logical_type(duckdb_result *result, idx_t col);
idx_t duckdb_column_count(duckdb_result *result);
idx_t duckdb_row_count(duckdb_result *result);
idx_t duckdb_rows_changed(duckdb_result *result);
void *duckdb_column_data(duckdb_result *result, idx_t col);
bool *duckdb_nullmask_data(duckdb_result *result, idx_t col);
const char *duckdb_result_error(duckdb_result *result);
duckdb_error_type duckdb_result_error_type(duckdb_result *result);
duckdb_query
在连接中执行 SQL 查询,并将完整(物化)结果存储在 out_result 指针中。如果查询执行失败,则返回 DuckDBError,并且可以通过调用 duckdb_result_error
来检索错误消息。
请注意,在运行 duckdb_query
之后,即使查询失败,也必须在结果对象上调用 duckdb_destroy_result
,否则存储在结果中的错误将无法正确释放。
语法
duckdb_state duckdb_query(
duckdb_connection connection,
const char *query,
duckdb_result *out_result
);
参数
connection
:要在其中执行查询的连接。query
:要运行的 SQL 查询。out_result
:查询结果。
返回值
成功时返回 DuckDBSuccess
,失败时返回 DuckDBError
。
duckdb_destroy_result
关闭结果并释放为该结果分配的所有内存。
语法
void duckdb_destroy_result(
duckdb_result *result
);
参数
result
:要销毁的结果。
duckdb_column_name
返回指定列的列名。结果不需要释放;列名将在结果销毁时自动销毁。
如果列超出范围,则返回 NULL
。
语法
const char *duckdb_column_name(
duckdb_result *result,
idx_t col
);
参数
result
:从中获取列名的结果对象。col
:列索引。
返回值
指定列的列名。
duckdb_column_type
返回指定列的列类型。
如果列超出范围,则返回 DUCKDB_TYPE_INVALID
。
语法
duckdb_type duckdb_column_type(
duckdb_result *result,
idx_t col
);
参数
result
:从中获取列类型的结果对象。col
:列索引。
返回值
指定列的列类型。
duckdb_result_statement_type
返回已执行语句的语句类型
语法
duckdb_statement_type duckdb_result_statement_type(
duckdb_result result
);
参数
result
:从中获取语句类型的结果对象。
返回值
duckdb_statement_type 值或 DUCKDB_STATEMENT_TYPE_INVALID
duckdb_column_logical_type
返回指定列的逻辑列类型。
此调用的返回类型应使用 duckdb_destroy_logical_type
销毁。
如果列超出范围,则返回 NULL
。
语法
duckdb_logical_type duckdb_column_logical_type(
duckdb_result *result,
idx_t col
);
参数
result
:从中获取列类型的结果对象。col
:列索引。
返回值
指定列的逻辑列类型。
duckdb_column_count
返回结果对象中存在的列数。
语法
idx_t duckdb_column_count(
duckdb_result *result
);
参数
result
:结果对象。
返回值
结果对象中存在的列数。
duckdb_row_count
警告:弃用通知。此方法计划在未来版本中移除。
返回结果对象中存在的行数。
语法
idx_t duckdb_row_count(
duckdb_result *result
);
参数
result
:结果对象。
返回值
结果对象中存在的行数。
duckdb_rows_changed
返回结果中存储的查询更改的行数。这仅与 INSERT/UPDATE/DELETE 查询相关。对于其他查询,rows_changed 将为 0。
语法
idx_t duckdb_rows_changed(
duckdb_result *result
);
参数
result
:结果对象。
返回值
更改的行数。
duckdb_column_data
已弃用 此方法已弃用。 建议改用
duckdb_result_get_chunk
。
以列格式返回结果的特定列的数据。
该函数返回一个包含结果数据的密集数组。 存储在数组中的确切类型取决于相应的 duckdb_type (由 duckdb_column_type
提供)。 有关应通过哪种确切类型访问数据的信息,请参见类型部分或 DUCKDB_TYPE
枚举中的注释。
例如,对于 DUCKDB_TYPE_INTEGER
类型的列,可以按以下方式访问行
int32_t *data = (int32_t *) duckdb_column_data(&result, 0);
printf("Data for row %d: %d\n", row, data[row]);
语法
void *duckdb_column_data(
duckdb_result *result,
idx_t col
);
参数
result
:从中获取列数据的结果对象。col
:列索引。
返回值
指定列的列数据。
duckdb_nullmask_data
已弃用 此方法已弃用。 建议改用
duckdb_result_get_chunk
。
以列格式返回结果的特定列的 nullmask。 nullmask 指示对于每一行,对应的行是否为 NULL
。 如果某一行是 NULL
,则 duckdb_column_data
提供的数组中的值是未定义的。
int32_t *data = (int32_t *) duckdb_column_data(&result, 0);
bool *nullmask = duckdb_nullmask_data(&result, 0);
if (nullmask[row]) {
printf("Data for row %d: NULL\n", row);
} else {
printf("Data for row %d: %d\n", row, data[row]);
}
语法
bool *duckdb_nullmask_data(
duckdb_result *result,
idx_t col
);
参数
result
:从中获取 nullmask 的结果对象。col
:列索引。
返回值
指定列的 nullmask。
duckdb_result_error
返回结果中包含的错误消息。 仅当 duckdb_query
返回 DuckDBError
时,才会设置该错误。
此函数的结果不得释放。 它将在调用 duckdb_destroy_result
时被清理。
语法
const char *duckdb_result_error(
duckdb_result *result
);
参数
result
:从中获取错误的结果对象。
返回值
结果的错误。
duckdb_result_error_type
返回结果中包含的结果错误类型。 仅当 duckdb_query
返回 DuckDBError
时,才会设置该错误。
语法
duckdb_error_type duckdb_result_error_type(
duckdb_result *result
);
参数
result
:从中获取错误的结果对象。
返回值
结果的错误类型。