C#中通过SQL查询指定日期范围内全表数据的问题
看起来你遇到的问题主要是两个点——一是WHERE条件的逻辑搞错了(你可能误把条件里的Auto换成了*,导致语法错误),二是当前的SQL只筛选了Auto列在日期区间内的记录,而你想要的是所有满足「任意动作时间在指定范围内」的全表数据。另外,你现在用字符串拼接SQL的方式存在严重安全隐患,得赶紧改成参数化查询,避免SQL注入。
一、先理清正确的SQL逻辑
你原来的SQL是SELECT * FROM Actions_Data WHERE Auto BETWEEN ...,这只会返回Auto列值在日期区间内的记录。如果想要所有列的数据,且只要记录中任意一个动作时间(Auto/Manual/Buttons_Off等)落在你选的日期范围内,那WHERE条件需要改成多个列的判断用OR连接,还要注意处理NULL值(因为你的datetime列都是允许NULL的):
SELECT * FROM Actions_Data WHERE (Auto IS NOT NULL AND Auto BETWEEN @StartDate AND @EndDate) OR (Manual IS NOT NULL AND Manual BETWEEN @StartDate AND @EndDate) OR (Buttons_Off IS NOT NULL AND Buttons_Off BETWEEN @StartDate AND @EndDate) OR (start_pump1 IS NOT NULL AND start_pump1 BETWEEN @StartDate AND @EndDate) OR (stop_pump1 IS NOT NULL AND stop_pump1 BETWEEN @StartDate AND @EndDate)
如果你的需求是「只要记录的某个动作发生在区间内就返回整个记录」,上面的SQL就完全符合要求。
二、用参数化查询替代字符串拼接
你现在直接把dateTimePicker的Value拼进SQL里,不仅容易因为日期格式问题出错,还会被黑客利用SQL注入攻击。换成参数化查询既安全又稳定,修改后的C#代码如下:
using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); // 用参数化的SQL语句,避免拼接风险 string sql = @"SELECT * FROM Actions_Data WHERE (Auto IS NOT NULL AND Auto BETWEEN @StartDate AND @EndDate) OR (Manual IS NOT NULL AND Manual BETWEEN @StartDate AND @EndDate) OR (Buttons_Off IS NOT NULL AND Buttons_Off BETWEEN @StartDate AND @EndDate) OR (start_pump1 IS NOT NULL AND start_pump1 BETWEEN @StartDate AND @EndDate) OR (stop_pump1 IS NOT NULL AND stop_pump1 BETWEEN @StartDate AND @EndDate)"; SqlDataAdapter sqlDa = new SqlDataAdapter(sql, con); // 直接传递DateTime类型参数,不用转字符串,避免格式问题 sqlDa.SelectCommand.Parameters.AddWithValue("@StartDate", dateTimePicker1.Value); sqlDa.SelectCommand.Parameters.AddWithValue("@EndDate", dateTimePicker2.Value); DataSet ds = new DataSet(); sqlDa.Fill(ds, "Actions_Data"); dataGridView1.DataSource = ds.Tables["Actions_Data"]; } // using块会自动释放连接资源,不用手动写con.Close()
三、为什么你之前用*不行?
你说「tried * in the position of Auto but it doesn't work」,应该是你错误地写成了SELECT * FROM Actions_Data WHERE * BETWEEN ...——这是语法错误,*只能用在SELECT后面表示选中所有列,WHERE条件里必须针对具体的列做判断,就像上面的SQL那样。
备注:内容来源于stack exchange,提问作者sakis

