⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
查询

duckdb_query 方法允许从 C 在 DuckDB 中运行 SQL 查询。此方法接受两个参数:一个 (null 结尾) SQL 查询字符串和一个 duckdb_result 结果指针。如果应用程序对结果集不感兴趣或者查询不产生任何结果,则结果指针可以为 NULL。在使用完结果后,应使用 duckdb_destroy_result 方法清理结果。

可以使用多种方法从 duckdb_result 对象中提取元素。 duckdb_column_count 可用于提取列数。 duckdb_column_nameduckdb_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:从中获取错误的结果对象。
返回值

结果的错误类型。