You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过DuckDB C API提取VARCHAR类型数据?

正确通过DuckDB C API提取VARCHAR类型字符串

在DuckDB 0.8.1的C API中,VARCHAR类型存储为duckdb_string_t结构,该结构采用**小字符串优化(SSO)**机制:

  • 当字符串长度≤12字节时,内容直接存入inlined数组
  • 当长度>12字节时,inlined数组存储的是指向堆中完整字符串的指针(并非压缩内容,你看到的特殊字节是指针的内存表示)

无需手动解析结构字节,DuckDB提供了专门的宏来安全获取字符串内容:

  • duckdb_string_get_length(str):获取字符串实际长度
  • duckdb_string_get_ptr(str):获取指向字符串内容的const char*指针

修正后的测试代码

// 省略数据库启动、连接及表创建/插入代码(与原代码一致)

duckdb_result result;
if (duckdb_query(con, "SELECT * FROM strings", &result) == DuckDBError) {
    fprintf(stderr, "Failed to query database3\n");
    goto cleanup;
}

// 使用data chunk和vector提取数据
duckdb_data_chunk res_chunk = duckdb_result_get_chunk(result, 0);
duckdb_vector vec = duckdb_data_chunk_get_vector(res_chunk, 0);
duckdb_logical_type type_l = duckdb_vector_get_column_type(vec);
duckdb_type type = duckdb_get_type_id(type_l);
printf("type id: %d\n", type);

// 转换为字符串数组指针
duckdb_string_t *string_array = (duckdb_string_t *)duckdb_vector_get_data(vec);
idx_t row_count = duckdb_data_chunk_get_size(res_chunk);

// 遍历提取每一行的字符串
for (idx_t i = 0; i < row_count; i++) {
    duckdb_string_t str = string_array[i];
    uint32_t str_len = duckdb_string_get_length(str);
    const char *str_ptr = duckdb_string_get_ptr(str);
    
    printf("Row %llu: length=%u, content='%.*s'\n", i, str_len, str_len, str_ptr);
}

cleanup:
// 清理资源
duckdb_data_chunk_destroy(&res_chunk);
duckdb_destroy_result(&result);
// 补充数据库断开、销毁等其他清理步骤

预期运行结果

type id: 17
Row 0: length=5, content='aaaaa'
Row 1: length=14, content='abcdrfghikjlmn'
Row 2: length=12, content='bbbbbbbbbbbb'

注意事项

  • 内存管理:duckdb_string_get_ptr返回的指针由DuckDB托管,无需手动释放,其有效性与对应的duckdb_vector/duckdb_data_chunk生命周期绑定,销毁chunk/vector前可安全访问。
  • 空值处理:如果结果包含NULL值,需先通过duckdb_vector_get_validity获取有效性掩码,判断当前行非NULL后再提取字符串,避免非法内存访问。

内容的提问来源于stack exchange,提问作者yiyang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 01:45:02