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

C# WinForm项目从Oracle读取BLOB文件保存到本地问题排查

C# Winform 读取Oracle BLOB字段存储到本地代码问题修复

现有代码核心问题

  • 字符串转义错误:定义tempDir的代码存在语法错误,C#中反斜杠为转义字符,网络路径要么用双反斜杠全转义,要么加@声明为逐字字符串,你写的末尾\还会和后接的引号冲突,编译都无法通过。
  • 查询字段不匹配:你写的SQL查询只返回了id、name、contenttype三个字段,没有包含存储文件的BLOB字段,且GetOracleBlob(1)读取的是name字段,该字段为字符串类型,根本不是BLOB格式,直接触发类型转换错误。
  • 资源泄漏风险:OracleDataReader、FileStream都没有用using包裹,异常场景下会出现资源未释放、文件句柄占用的问题。
  • 逻辑冗余错误:你写了遍历dataTable的循环,但硬编码了SQL的查询条件id=3,注释掉了参数化代码,循环完全不生效,每次查询的都是同一条记录;且数据库连接创建、打开的逻辑写在循环内,每次循环都新建连接,性能极低。
  • 无结果校验:没有判断OracleDataReader.Read()的返回值,如果查询无数据,直接读取字段会抛空引用/索引越界异常。

修复后可运行代码

// 逐字字符串避免转义问题,也可以替换为本地下载目录:Environment.GetFolderPath(Environment.SpecialFolder.Downloads)
string tempDir = @"\\NB17-KP-239\Downloads\";
// 连接字符串放到循环外,复用连接
string oradbConString = "Data Source = localhost; Persist Security Info = True; User ID = homeuser; Password = admin;";
using (OracleConnection oraCon = new OracleConnection(oradbConString))
{
    oraCon.Open();
    for (int index = 0; index < dataTable.Rows.Count; ++index)
    {
        using (OracleCommand comOra = oraCon.CreateCommand())
        {
            // 增加BLOB字段content,替换为你实际的BLOB字段名,用参数化查询避免注入风险
            comOra.CommandText = "select id,name,content,contenttype from blob_sample where id = :Id";
            comOra.Parameters.Add("Id", dataTable.Rows[index]["id"]);
            using (OracleDataReader oracleDataReader = comOra.ExecuteReader())
            {
                // 校验是否有查询结果再操作
                if (oracleDataReader.Read())
                {
                    // content字段是索引2,对应BLOB字段,注意字段顺序要和查询语句一致
                    OracleBlob oracleBlob = oracleDataReader.GetOracleBlob(2);
                    string fileName = oracleDataReader.GetString(1); // 取name字段作为文件名,可按需加后缀
                    string path = Path.Combine(tempDir, fileName);
                    // FileStream用using包裹自动释放资源,不需要手动调用Close
                    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
                    {
                        byte[] buffer = new byte[oracleBlob.Length];
                        int count = oracleBlob.Read(buffer, 0, Convert.ToInt32(oracleBlob.Length));
                        fileStream.Write(buffer, 0, count);
                    }
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 02:27:03