C# ODBC查询结果写入文本文件提示reader已关闭错误如何解决
问题根因
DataTable.Load(sqlReader)执行完成后会自动关闭传入的OdbcDataReader实例,后续调用sqlReader.Read()自然会抛出 reader 已关闭的异常。- 逻辑冗余:你已经将全量查询结果加载到了
DataTable对象中,不需要再通过OdbcDataReader二次读取数据,外层的while (sqlReader.Read())属于完全无用的错误逻辑。 - 列名写入逻辑位置错误:放在循环内会导致列名被重复写入,正常仅需在文件首行写入一次。
修复后可运行代码
using System; using System.IO; using System.Data.Odbc; using System.Data; using System.Linq; namespace Testing_Studio { class Program { static void Main(string[] args) { string sqlQuery = File.ReadAllText(@"C:\Users\Test\Desktop\Testing_Studio\Script_2.txt"); // 使用using自动释放ODBC相关资源,无需手动调用Close using var conn = new OdbcConnection("Dsn=Test;uid=Test;pwd=Test"); using var comm = new OdbcCommand(sqlQuery, conn); conn.Open(); using OdbcDataReader sqlReader = comm.ExecuteReader(); var dataTable = new DataTable(); dataTable.Load(sqlReader); using StreamWriter writer = new StreamWriter(@"C:\Users\Test\Desktop\Testing_Studio\output.txt"); // 仅写入一次列名 var columnNames = dataTable.Columns.OfType<DataColumn>().Select(x => x.ColumnName); writer.WriteLine(string.Join("\t", columnNames)); int columnCount = dataTable.Columns.Count; string[] values = new string[columnCount]; // 直接遍历DataTable的行写入数据,不需要再操作DataReader foreach (DataRow row in dataTable.Rows) { for (int i = 0; i < columnCount; i++) { object value = row[i]; values[i] = value != null ? value.ToString() : "NULL"; } writer.WriteLine(string.Join("\t", values)); } } } }
额外优化说明
- 所有实现了
IDisposable接口的数据库相关对象(连接、命令、DataReader)都用using块包裹,程序执行到作用域结束后会自动释放资源,不需要手动调用Close方法,避免资源泄漏。 - 列名写入逻辑移到循环外,避免重复写入。
- 移除了无用的
DataReader读取逻辑,直接从已加载完成的DataTable中取数写入文件。
内容的提问来源于stack exchange,提问作者Kyle Brown
相关产品推荐
相关产品推荐

