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

如何在rustqlite中获取可为空或空值的列数据?

解决rusqlite处理NULL TEXT字段的panic问题

错误原因

你遇到的InvalidColumnType(0, "name", Null)错误,是因为数据库中name字段为NULL,但你直接用row.get(0).unwrap()尝试将其转换为String——而Rust的String不允许为NULL,rusqlite无法完成这个转换,因此触发panic。

解决方案

核心思路是用Option<String>接收数据库返回的字段值(NULL对应None),再将None转为你需要的空字符串,具体实现如下:

修改后的代码

use rusqlite::{Connection, Result};

fn main() -> Result<()> {
    // Open connection
    let conn = Connection::open(":memory:")?;

    // Create test_table
    conn.execute(
        "CREATE TABLE IF NOT EXISTS test_table (
            id                 INTEGER PRIMARY KEY,
            name               TEXT
        )", (),
    )?;

    // Insert demo row
    conn.execute("INSERT INTO test_table (id) VALUES (?1)", [1])?;

    // Prepare an empty vector to store column data even if is empty string
    let mut result: Vec<String> = Vec::new();

    // The actual query
    conn.query_row("SELECT name FROM test_table WHERE id = ?1", [1], |row| {
        // 将字段值转为Option<String>,NULL对应None
        let name: Option<String> = row.get(0)?;
        // 把None替换成空字符串,存入vector
        result.push(name.unwrap_or_default());
        Ok(())
    })?;

    println!("Result: {:?}", result);
    Ok(())
}

关键修改点

  • 用Option<String>接收row.get(0)的结果:rusqlite会自动将数据库TEXT类型的NULL映射为None,非NULL值映射为Some(String)。
  • 使用unwrap_or_default()将None转为空字符串(String::default()就是空字符串),满足你需要存储空字符串的需求。
  • 全程用?替代unwrap()处理错误,避免不必要的panic,同时让代码更简洁。

关于循环的疑问

你提到想用while+match处理结果,但query_row本身就是用于获取单行数据的API,不需要循环。如果要处理多行数据,应该用query方法配合迭代器:

// 处理多行的示例
let mut stmt = conn.prepare("SELECT name FROM test_table")?;
let name_iter = stmt.query_map([], |row| {
    let name: Option<String> = row.get(0)?;
    Ok(name.unwrap_or_default())
})?;

for name in name_iter {
    result.push(name?);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:42:39