尝试从 WPF 中的 Access 数据库中获取给定条件的日期时出错

Posted

技术标签:

【中文标题】尝试从 WPF 中的 Access 数据库中获取给定条件的日期时出错【英文标题】:Error when trying to get dates given a condition from Access database in WPF 【发布时间】: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

提前谢谢你。

【问题讨论】:

如果在此处检查:***.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' 【参考方案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 函数。谢谢!

【讨论】:

以上是关于尝试从 WPF 中的 Access 数据库中获取给定条件的日期时出错的主要内容,如果未能解决你的问题,请参考以下文章

使用 WPF 成功连接后无法从 Access 数据库获取数据

无法将 access_token 传递给 Reactjs 中的端点

从 wpf 页面中的组合框(在用户控件中)获取数据

通过 WPF 应用程序从 Access (.accdb) 中检索查询、表单和报表属性

如何从 Access VBA 中的另一个私有子获取私有子中声明的变量的值

如何从 C# 中的 DatePicker(WPF) 中获取价值?