C#轮询SQL数据库逻辑异常问题排查
控制台C#服务轮询SQL表行数的问题解决
问题描述
开发控制台形式的C#服务,用于轮询SQL数据库表的行数,当有新行插入时触发后续处理,但轮询逻辑存在问题:
- 调试时发现DataTable行数与
prevRowCount均为2,却仍进入if分支; - 每次执行
adapter.Fill后,DataTable行数持续累加。
疑问:
- 使用当前代码结构是否需要在循环中清理变量?若需要,如何操作?
- 首次循环时两者值均为2,为何会进入
if分支?
原代码:
namespace ConsoleApp2 { class Program { static void Main(string[] args) { //1 second pause SqlConnection conn = new SqlConnection(@"OMITTED"); //connection to DB conn.Open(); SqlDataAdapter adapter = new SqlDataAdapter("OMITTED", conn); //Query to fil poll table comparator DataTable table = new DataTable(); //establishing new instance to fill adapter.Fill(table); int prevRowCount = table.Rows.Count; // establishing comparator value while (true) //loop { adapter.Fill(table); if (table.Rows.Count > prevRowCount) { Console.WriteLine("New records"); prevRowCount = table.Rows.Count; } Thread.Sleep(1000); //1 second pause } } } }
问题分析与解答
核心问题根源
SqlDataAdapter.Fill()方法的默认行为是将查询结果追加到目标DataTable中,而非覆盖原有数据。这是导致行数持续累加、逻辑判断异常的根本原因。
疑问1解答:需要在循环中清理数据,两种可行方案
必须清理DataTable中的旧数据,否则每次Fill都会追加新查询结果,导致行数不断增长。推荐两种方式:
- 方案1:清空DataTable(高效推荐)
在每次调用adapter.Fill()前,调用table.Clear()清空所有行数据,确保每次Fill都是最新的查询结果:while (true) { table.Clear(); // 清空旧数据 adapter.Fill(table); // 后续判断逻辑 } - 方案2:每次循环重新创建DataTable
在循环内重新实例化DataTable,避免旧数据残留:while (true) { DataTable table = new DataTable(); adapter.Fill(table); // 后续判断逻辑 }
另外,补充优化:使用using语句包裹SqlConnection和SqlDataAdapter,自动释放数据库资源,避免泄漏:
using (SqlConnection conn = new SqlConnection(@"OMITTED")) using (SqlDataAdapter adapter = new SqlDataAdapter("OMITTED", conn)) { conn.Open(); // 后续逻辑 }
疑问2解答:首次循环进入分支的原因
首次循环时,你看到的“两者值均为2”是Fill之前的状态:
- 初始化阶段:
adapter.Fill(table)查询到2行,prevRowCount = 2; - 进入首次循环:执行
adapter.Fill(table),由于Fill是追加行为,table的行数变成2+2=4; - 此时
table.Rows.Count(4) > prevRowCount(2),满足条件进入分支。
你调试时可能没有断点在Fill之后,误判了行数状态。
修正后的完整代码
namespace ConsoleApp2 { class Program { static void Main(string[] args) { using (SqlConnection conn = new SqlConnection(@"OMITTED")) using (SqlDataAdapter adapter = new SqlDataAdapter("OMITTED", conn)) { conn.Open(); DataTable table = new DataTable(); adapter.Fill(table); int prevRowCount = table.Rows.Count; while (true) { table.Clear(); adapter.Fill(table); if (table.Rows.Count > prevRowCount) { Console.WriteLine("New records"); prevRowCount = table.Rows.Count; } System.Threading.Thread.Sleep(1000); } } } } }
内容的提问来源于stack exchange,提问作者TyranitarOverlord
相关产品推荐
相关产品推荐

