【问题标题】:Error when trying to get dates given a condition from Access database in WPF尝试从 WPF 中的 Access 数据库中获取给定条件的日期时出错
【发布时间】:2019-10-08 07:21:15
【问题描述】:

我正在开发一个 WPF 应用程序,它将用户注册和日期保存到 Access 数据库中。 我插入日期没有问题,但现在我想用 DataReader 检索给定条件的一些日期(例如,当月的所有日期)。 当我尝试通过我的应用程序读取它时,DataReader 不返回任何行。但是当我在 DBeaver 上尝试相同的查询时,它确实返回了数据。

只有当我尝试在特定条件下读取日期时才会出现此读取问题,因为如果我尝试读取所有日期,则没有问题。

我尝试过使用参数化命令并直接使用String.Format() 插入条件。

我目前有这个功能(如果我们不计算数据库中保存的天数,它会尝试计算一个月中还剩下多少天):

public static int CalculateDaysLeftInMonth()
{
    int days = 0;
    List<DateTime> dates = new List<DateTime>();

    try
    {
        if (dbConnection.State != ConnectionState.Open)
            dbConnection.Open();

       OleDbCommand dbCommandQuery = new OleDbCommand {
            CommandText = "SELECT * FROM DatesTable WHERE Date LIKE @Condition"
        }

        dbCommandQuery.Parameters.AddWithValue("@Condition", String.Format("{0:yyyy-MM}-%", DateTime.Now));

        OleDbDataReader dbReader = dbCommandQuery.ExecuteReader();

        if (!dbReader.HasRows)
            return -1;

        while (dbReader.Read())
        {
            dates.Add(new FechaFestivo(dbReader.GetDateTime(0).Date));
        }

        dbConnection.Close();

        DateTime startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1),
                 endDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 
                           DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month));

        for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
        {
            if (!dates.Any(ff => ff.Date == date.Date))
            {
                days++;
            }
        }
    }
    catch (OleDbException ex)
    {
        dbConnection.Close();
        return -1;
    }

    return days;
}

这是参数化版本。 我也试过使用:

dbCommandQuery.CommandText = String.Format("SELECT * FROM DatesTable WHERE Date " +
"LIKE '{0:yyyy-MM}-%'", DateTime.Now);

我希望得到一个这样的日期列表,所以我可以遍历它们:

CalendarioLaboral 将是 DatesTableFechaFestivo 将是 Dates

提前谢谢你。

【问题讨论】:

  • 如果在此处检查:stackoverflow.com/questions/1629050/… DateTime 不支持 LIKE(为什么应该这样做是没有意义的),但如果您想使用它,可以转换为 VARCHAR。
  • @Holger 谢谢!我尝试使用这个:dbCommandQuery.CommandText = String.Format("SELECT * FROM {0} WHERE (DATEPART(yyyy, FechaFestivo) = {1:yyyy} AND DATEPART (mm, FechaFestivo) = {1:MM})", TablaCalendario, DateTime.Now); 但它给了我一个 OleDbException (没有为一些需要的参数指定值)。是不是应该换成别的写法?再次感谢您!
  • 您最好在 string.Format 执行后提供生成的 CommandText。这似乎是一个纯 SQL 问题,与 C# 完全无关。我不确定 TablaCalendario 是什么,也许是 ToString() 方法产生了一些奇怪的东西。
  • @Holger 生成的CommandText是"SELECT * FROM CalendarioLaboral WHERE (DATEPART(yy, FechaFestivo) = 2019 AND DATEPART (mm, FechaFestivo) = 10)",而TablaCalendario只是一个包含表名的字符串。很抱歉给您带来不便,我的问题恰恰是在我的 C# 代码中,这个查询不起作用,但在 DBeaver 这样的 SQL 客户端中它确实有效......虽然如果这个问题不在正确的地方,我会编辑标签。
  • mmyyyy 参数需要在生成的 SQL 字符串中包含在撇号分隔符中。必须是 'yyyy''mm'

标签: c# wpf ms-access c#-4.0 oledb


【解决方案1】:

Like '2019-10-%',表示2019年10月的一天,所以相当于date between 2019-10-01 AND 2019-10-31。试试看:

SELECT * FROM DatesTable WHERE Date between '2019-10-01' AND' 2019-10-31'

【讨论】:

    【解决方案2】:

    最后对我有用的代码如下:

    public static int CalculateDaysLeftInMonth()
    {
        int days = 0;
        List<DateTime> dates = new List<DateTime>();
    
        try
        {
            if (dbConnection.State != ConnectionState.Open)
                dbConnection.Open();
    
           OleDbCommand dbCommand = new OleDbCommand {
               CommandText = String.Format("SELECT * FROM {0} WHERE (DATEPART('yyyy', FechaFestivo) = @Year " +
                                           "AND DATEPART ('m', FechaFestivo) = @Month)", TablaCalendario)
           }
    
           dbCommandQuery.Parameters.AddWithValue("@Year", DateTime.Now.Year);
           dbCommandQuery.Parameters.AddWithValue("@Month", DateTime.Now.Month);
    
            OleDbDataReader dbReader = dbCommandQuery.ExecuteReader();
    
            if (!dbReader.HasRows)
                return -1;
    
            while (dbReader.Read())
            {
                dates.Add(new FechaFestivo(dbReader.GetDateTime(0).Date));
            }
    
            dbConnection.Close();
    
            DateTime startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1),
                     endDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 
                               DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month));
    
            for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
            {
                if (!dates.Any(ff => ff.Date == date.Date))
                {
                    days++;
                }
            }
        }
        catch (OleDbException ex)
        {
            dbConnection.Close();
            return -1;
        }
    
        return days;
    }
    

    在 cmets 中使用 @Holger 和 @June7 中所说的 DatePart 函数。谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-08
      • 2019-11-07
      • 1970-01-01
      • 2019-09-03
      • 2020-04-22
      • 2018-10-23
      • 2020-07-25
      • 1970-01-01
      相关资源
      最近更新 更多