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

C#轮询SQL数据库逻辑异常问题排查

控制台C#服务轮询SQL表行数的问题解决

问题描述

开发控制台形式的C#服务,用于轮询SQL数据库表的行数,当有新行插入时触发后续处理,但轮询逻辑存在问题:

  • 调试时发现DataTable行数与prevRowCount均为2,却仍进入if分支;
  • 每次执行adapter.Fill后,DataTable行数持续累加。

疑问:

  1. 使用当前代码结构是否需要在循环中清理变量?若需要,如何操作?
  2. 首次循环时两者值均为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之前的状态:

  1. 初始化阶段:adapter.Fill(table)查询到2行,prevRowCount = 2;
  2. 进入首次循环:执行adapter.Fill(table),由于Fill是追加行为,table的行数变成2+2=4;
  3. 此时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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:31:07