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

C# UWP中SQLite WHERE子句使用Input.Text传参与空值报错解决

问题根因

你当前的代码存在3个直接导致异常和隐患的问题:

  • 字符串拼接SQL时引号转义逻辑错误:你手动拼接的条件最终生成的SQL中,画廊名称被错误包裹了转义双引号,而非SQL语法要求的单引号,导致WHERE条件无法匹配到任何画廊记录。avg()聚合函数在无匹配行时会返回NULL,直接调用GetDouble(0)读取NULL值就触发了你看到的InvalidOperationException。
  • 字符串拼接用户输入属于明确的反模式:存在SQL注入风险,且无法自动处理输入中包含单引号、特殊字符的场景,哪怕是本地应用也不推荐使用。
  • 代码存在逻辑缺陷:读取结果前未做DBNull校验,数据库连接关闭的代码被截断(dataManager.database.Clos),会引发后续连接泄漏问题。
修复方案(遵循C# SQLite最佳实践)

核心是改用参数化查询,完全放弃手动拼接用户输入到SQL字符串的写法,参数化会自动处理语法转义、特殊字符匹配,从根源避免注入和引号写错的问题。

1. 修正按钮点击事件逻辑

private void totalWorthBtn_Click(object sender, RoutedEventArgs e)
{
    // SQL语句用@参数名做占位符,不拼接任何用户输入
    const string querySql = @"
        SELECT round(avg(Artwork.worth),2) as avgArtworkWorth, Gallery.galleryName 
        FROM Gallery 
        INNER JOIN Artwork ON Gallery.GalleryID = Artwork.galleryiD 
        WHERE Gallery.galleryName = @galleryName;";

    // 传入参数执行查询,不需要给参数值加任何引号
    dataManager.ArtworkAvgQuery(querySql, new Dictionary<string, object>
    {
        {"@galleryName", Input.Text.Trim()}
    });

    double avgWorth = 0;
    string matchedGallery = string.Empty;

    while (dataManager.queryResult.Read())
    {
        // 读取值前必须先判断是否为DBNull
        if (!dataManager.queryResult.IsDBNull(0))
        {
            avgWorth = dataManager.queryResult.GetDouble(0);
        }
        if (!dataManager.queryResult.IsDBNull(1))
        {
            matchedGallery = dataManager.queryResult.GetString(1);
        }

        if (firstPass)
        {
            counter++;
        }
        Debug.WriteLine($"查询结果:画廊{matchedGallery}的艺术品平均价值为{avgWorth}");
    }

    firstPass = false;
    // 正确关闭结果集和数据库连接,不要写截断代码
    dataManager.queryResult.Close();
    dataManager.database.Close();

    // 可选:无匹配结果时给用户提示
    if (string.IsNullOrEmpty(matchedGallery))
    {
        // 这里可以加弹窗提示"未找到对应画廊的记录"
    }
}

2. 调整SQLManage类的查询方法支持参数传递

// 重构查询方法,支持接收参数集合
public void ArtworkAvgQuery(string sql, Dictionary<string, object> sqlParams = null)
{
    // 以下是基于Microsoft.Data.Sqlite的通用实现,如果你用其他SQLite驱动逻辑一致
    using (var cmd = new SQLiteCommand(sql, database))
    {
        // 自动加载传入的参数,驱动会自动处理转义、类型匹配
        if (sqlParams != null)
        {
            foreach (var param in sqlParams)
            {
                cmd.Parameters.AddWithValue(param.Key, param.Value);
            }
        }
        // 执行查询赋值给公共的queryResult字段
        queryResult = cmd.ExecuteReader();
    }
}
验证说明

按照你的测试数据,输入CatLand时,会正确匹配到ID为4的画廊,关联2件艺术品计算出平均价值为45250,不会出现NULL异常。如果输入不存在的画廊名称,DBNull判断逻辑会拦截异常,你可以自定义无匹配时的交互提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:54:25