duckdb_query
方法允许在 DuckDB 中从 C 语言运行 SQL 查询。该方法接受两个参数,一个(以 null 结尾的)SQL 查询字符串和一个 duckdb_result
结果指针。如果应用程序对结果集不感兴趣或查询不产生结果,结果指针可以为 NULL
。在结果被使用后,应使用 duckdb_destroy_result
方法来清理结果。
可以使用多种方法从duckdb_result
对象中提取元素。duckdb_column_count
可用于提取列的数量。duckdb_column_name
和duckdb_column_type
可用于提取单个列的名称和类型。
Example
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
函数执行边界和类型检查,并会自动将值转换为所需类型。这使得它们更方便和易于使用,但代价是速度较慢。
请参阅Types页面以获取更多信息。
为了获得最佳性能,请使用
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 Reference Overview
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
,否则存储在结果中的错误将无法正确释放。
Syntax
duckdb_state duckdb_query(
duckdb_connection connection,
const char *query,
duckdb_result *out_result
);
Parameters
connection
: 执行查询的连接。query
: 要运行的SQL查询。out_result
: 查询结果。
Return Value
DuckDBSuccess
on success or DuckDBError
on failure.
duckdb_destroy_result
关闭结果并释放为该连接分配的所有内存。
Syntax
void duckdb_destroy_result(
duckdb_result *result
);
Parameters
result
: 要销毁的结果。
duckdb_column_name
返回指定列的名称。结果不需要手动释放;当结果被销毁时,列名将自动销毁。
如果列超出范围,则返回 NULL
。
Syntax
const char *duckdb_column_name(
duckdb_result *result,
idx_t col
);
Parameters
result
: 从中获取列名的结果对象。col
: 列索引。
Return Value
指定列的名称。
duckdb_column_type
返回指定列的类型。
如果列超出范围,则返回 DUCKDB_TYPE_INVALID
。
Syntax
duckdb_type duckdb_column_type(
duckdb_result *result,
idx_t col
);
Parameters
result
: 从中获取列类型的结果对象。col
: 列索引。
Return Value
指定列的类型。
duckdb_result_statement_type
返回已执行语句的语句类型
Syntax
duckdb_statement_type duckdb_result_statement_type(
duckdb_result result
);
Parameters
result
: 用于获取语句类型的结果对象。
Return Value
duckdb_statement_type 值或 DUCKDB_STATEMENT_TYPE_INVALID
duckdb_column_logical_type
返回指定列的逻辑列类型。
此调用的返回类型应使用duckdb_destroy_logical_type
销毁。
Returns NULL
if the column is out of range.
Syntax
duckdb_logical_type duckdb_column_logical_type(
duckdb_result *result,
idx_t col
);
Parameters
result
: 从中获取列类型的结果对象。col
: 列索引。
Return Value
指定列的逻辑列类型。
duckdb_column_count
返回结果对象中存在的列数。
Syntax
idx_t duckdb_column_count(
duckdb_result *result
);
Parameters
result
: 结果对象。
Return Value
结果对象中存在的列数。
duckdb_row_count
警告 弃用通知。此方法计划在未来的版本中移除。
返回结果对象中存在的行数。
Syntax
idx_t duckdb_row_count(
duckdb_result *result
);
Parameters
result
: 结果对象。
Return Value
结果对象中存在的行数。
duckdb_rows_changed
返回存储在结果中的查询更改的行数。这仅与INSERT/UPDATE/DELETE查询相关。对于其他查询,rows_changed将为0。
Syntax
idx_t duckdb_rows_changed(
duckdb_result *result
);
Parameters
result
: 结果对象。
Return Value
更改的行数。
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]);
Syntax
void *duckdb_column_data(
duckdb_result *result,
idx_t col
);
Parameters
result
: 从中获取列数据的结果对象。col
: The column index.
Return Value
指定列的列数据。
duckdb_nullmask_data
已弃用 此方法已被弃用。建议使用
duckdb_result_get_chunk
代替。
返回以列格式表示的特定列结果的空值掩码。空值掩码指示每一行是否是对应的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]);
}
Syntax
bool *duckdb_nullmask_data(
duckdb_result *result,
idx_t col
);
Parameters
result
: 从中获取空掩码的结果对象。col
: The column index.
Return Value
指定列的空掩码。
duckdb_result_error
返回结果中包含的错误信息。只有在duckdb_query
返回DuckDBError
时才会设置错误。
此函数的结果不能被释放。它将在调用duckdb_destroy_result
时被清理。
Syntax
const char *duckdb_result_error(
duckdb_result *result
);
Parameters
result
: 从中获取错误的结果对象。
Return Value
结果的错误。
duckdb_result_error_type
返回结果中包含的错误类型。只有在duckdb_query
返回DuckDBError
时,错误才会被设置。
Syntax
duckdb_error_type duckdb_result_error_type(
duckdb_result *result
);
Parameters
result
: 从中获取错误的结果对象。
Return Value
结果的错误类型。