⌘+k ctrl+k
1.1.3 (stable)
Search Shortcut cmd + k | ctrl + k
Query

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

可以使用多种方法从duckdb_result对象中提取元素。duckdb_column_count可用于提取列的数量。duckdb_column_nameduckdb_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

结果的错误类型。