首页 > 解决方案 > C# windows 窗体在 datagridview 中显示 0,其中按小时分组的数据,但 SQL 开发人员显示正确的结果

问题描述

我在 Oracle 中有一个查询,按小时显示事务数,然后最后一列显示所有小时的总和。该查询在 SQL 开发人员中运行良好。但是,当我尝试在我的 Windows 窗体应用程序的 datagridview 中显示结果时,我得到所有小时数据的 0。但是,我确实得到了最终总数。

这是我第一次在使用日期选择器和在 datagridview 中显示数据时遇到问题。

这是 SQL developer 中结果的屏幕截图(我意识到总列不等于显示的列的总数。屏幕截图未显示所有列。)

在此处输入图像描述

这是窗口表单中相同数据的屏幕截图。

在此处输入图像描述

这就是我认为是相关的 SQL 代码。如果过分请见谅。

SELECT
 user_name,
 SUM(CASE
     WHEN substr(hr,11) = '19:00:00' THEN t
     ELSE 0
 END) AS eight_pm,
 SUM(CASE
     WHEN substr(hr,11) = '20:00:00' THEN t
     ELSE 0
 END) AS nine_pm,
 SUM(CASE
     WHEN substr(hr,11) = '21:00:00' THEN t
     ELSE 0
 END) AS ten_pm,
 SUM(CASE
     WHEN substr(hr,11) = '22:00:00' THEN t
     ELSE 0
 END) AS eleven_pm,
 SUM(t) total
 FROM
 (
     SELECT
         user_name,
         COUNT(*) t,
         TO_CHAR(trunc(last_update_date,'HH24') ) AS hr
     FROM
         cte
     GROUP BY
         user_name,
         TO_CHAR(trunc(last_update_date,'HH24') )
 )
 GROUP BY
 user_name
 ORDER BY
 user_name

除了将日期选择器用作参数来查询数据之外,我没有对日期选择器做任何事情。如有必要,我可以显示自定义格式或一些 C# 代码。

请注意,直到明天早上我才能测试任何解决方案。感谢您的时间。

更新 添加用于填充 datagridview 的代码:

 private void btnSecondShiftStats_Click(object sender, EventArgs e)
    {
        var start = startDatePicker.Value;
        var end = endDatePicker.Value;
        string name = tbName.Text;

        dvgSecondShiftStats.DataSource = _secondShiftStatsData.GetStats(start, end, name);
    }

GetStats 方法:

   public List<SecondShiftStats> GetStats(DateTime fromDate, DateTime toDate, string uName)
    {
        var statList = new List<SecondShiftStats>();
        var conString = ConfigurationManager.ConnectionStrings["SecondShiftStatsConnection"].ConnectionString;
        using (OracleConnection con = new OracleConnection(conString))
        {
            string sql = @"WITH loaded AS (
                                             SELECT...";

            using (OracleCommand cmd = new OracleCommand(sql, con))
            {
                cmd.Parameters.Add(new OracleParameter(":start_time", OracleDbType.Date)).Value = fromDate;
                cmd.Parameters.Add(new OracleParameter(":end_time", OracleDbType.Date)).Value = toDate;

                cmd.Parameters.Add("name", uName);

                con.Open();
                using (OracleDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var stats = new SecondShiftStats();
                        stats.USER_NAME = reader["USER_NAME"].ToString();
                        stats.THREE_PM = Convert.ToInt32(reader["THREE_PM"]);
                        stats.FOUR_PM = Convert.ToInt32(reader["FOUR_PM"]);
                        stats.FIVE_PM = Convert.ToInt32(reader["FIVE_PM"]);
                        stats.SIX_PM = Convert.ToInt32(reader["SIX_PM"]);
                        stats.SEVEN_PM = Convert.ToInt32(reader["SEVEN_PM"]);
                        stats.EIGHT_PM = Convert.ToInt32(reader["EIGHT_PM"]);
                        stats.NINE_PM = Convert.ToInt32(reader["NINE_PM"]);
                        stats.TEN_PM = Convert.ToInt32(reader["TEN_PM"]);
                        stats.ELEVEN_PM = Convert.ToInt32(reader["ELEVEN_PM"]);
                        stats.TOTAL = Convert.ToInt32(reader["TOTAL"]);

                        statList.Add(stats);
                    }
                }

            } 

        }
        return statList;
    }

标签: c#oraclewinformsdatagridview

解决方案


我想出了解决这个问题的办法。我有另一个应用程序显示相同的查询,但没有分组。我在 sql developer 和 datagridview 中看到了日期时间格式的差异。

SQL开发人员:

在此处输入图像描述

数据网格视图:

在此处输入图像描述

最后是 Datetimepicker 的格式:

在此处输入图像描述

我从未改变 datgridview 显示日期的方式。我只自定义了 datetimepicker 并将其用作查询中的参数。这似乎是问题所在。

因此,我将 select 语句中的相关列更改为:

TO_CHAR(last_update_date, 'DD/MON/YYYY HH24:MI:SS')AS last_update_date.

当然,我知道我必须将最终选择更改为:

select ...
case when substr(hr,11)...

select ...
case when substr(hr,13)...

或者我是这么想的。当我尝试在 SQL Developer 中运行查询时,我会收到 ORA-01722: invalid-number 消息。

我再次确定它在分组语句中,并寻找按小时分组的其他解决方案。我尝试使用此Stack Overflow question中接受的答案,但收到一条消息,指出小时数必须在 1 到 12 之间,即使我的格式设置为“HH24”。

为了解决这个问题,我将最终的子查询更改为:

SELECT
 user_name,
 SUM(CASE
     WHEN hr = '19' THEN t
     ELSE 0
 END) AS eight_pm,
 SUM(CASE
     WHEN hr  = '20' THEN t
     ELSE 0
 END) AS nine_pm,
 SUM(CASE
     WHEN hr = '21' THEN t
     ELSE 0
 END) AS ten_pm,
 SUM(CASE
     WHEN hr = '22' THEN t
     ELSE 0
 END) AS eleven_pm,
 SUM(t) total
 FROM
 (
     SELECT
         user_name,
         COUNT(*) t,
         substr(last_update_date,13,2)as hr
     FROM
         cte
     GROUP BY
         user_name,
        substr(last_update_date,13,2)
 )
 group by
 user_name
 order by
 user_name

进行这些更改后,我的应用程序会显示我期望的结果:

在此处输入图像描述


推荐阅读