【问题标题】:Retrieve Data from Sqllite DB between Two dates android在两个日期之间从 Sqlite DB 检索数据 android
【发布时间】:2014-02-03 14:01:57
【问题描述】:

我在两个日期之间检索数据,一些如何获得正确的结果,一些如何在我选择带有月份的日期时输出空列表视图,但当我选择超过一个月的日期时,它输出空列表视图下面是我的代码

这里我在 DB 类中声明变量

public static final String EX_RowID = "_id";
public static final String EX_Cattype = "Ecattype";
public static final String EX_Date = "Ecdate";
public static final String EX_Price = "Ecprice";
public static final String EX_Type = "itype";

建表语句

    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        db.execSQL("CREATE TABLE " + Food_TABLE +"(" +
                EX_RowID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                EX_Cattype + " TEXT NOT NULL, " +
                EX_Date + " TEXT NOT NULL," +
                EX_Price + " INTEGER NOT NULL," +
                EX_Type + " TEXT NOT NULL UNIQUE );"
                );

    }

输入数据方法

 public long ExEntry(String Ecatgtype, String Edate, String Eprice, String Eitype) {
// TODO Auto-generated method stub

ContentValues cv = new ContentValues();
cv.put(EX_Cattype, Ecatgtype);
cv.put(EX_Date, Edate );
cv.put(EX_Price, Eprice);
cv.put(EX_Type, Eitype);
return ourdatabase.insertOrThrow(Food_TABLE, null, cv);
 }

这里我访问 ExEntry 方法

ExMgDB Expentry = new ExMgDB(ADD_EX.this);
    Expentry.open();
    Expentry.ExEntry(cate, date, price, itype);
    Expentry.close();

这里我面临这两个日期变量之间的问题

 public Cursor CstmRpot(String fd, String td) {
// TODO Auto-generated method stub
String[] columns = new String[] {EX_RowID,EX_Cattype, EX_Date, EX_Price, EX_Type };
Cursor c= ourdatabase.query(Food_TABLE, columns, EX_Date  + " BETWEEN '" + fd + "'  
 AND '" + td + "'" , null, null, null, null);
if (c != null) {

       c.moveToFirst();

      }
return c;

}

我像下面这样访问它

 CustemRpt dbcs = new CustemRpt();    
Cursor cursor = CstDB.CstmRpot(frmdate,tondate);

【问题讨论】:

  • 您如何在 Ecdate 字段中存储日期值?如果您使用字符串字段来存储日期,请确保作为字符串的排序对于相应的日期也有效。为此,您应该将日期存储为 yyyymmdd
  • 所以当我改变甲酸盐时,你认为这是正确的结果
  • 订购是什么意思
  • 要获取两个日期之间的数据范围,数据库引擎需要获取有序列表,不是吗?
  • 我做了你的方法,但问题存在

标签: java android sqlite


【解决方案1】:

有两种主要的解决方案。所有解决方案都有一个共同点,即必须以某种方式对包含日期的列进行排序。如果此订单被破坏,则您的数据已损坏并且您的查询无法返回预期结果!

1.在数据库中将您的日期保存为INTEGER,并使用一种方法将日期映射到一个数字:

一种可能的方法是使用Date.getTime () 将日期映射到数字,但还有很多其他方法。重要的是

  1. 相同的日期得到相同的数字和
  2. 在另一个日期之后的日期获得更大的数字。

这样排序肯定是正确的。 要使用 `Java.util.Date.getTime() 实现这一点,如果您只想存储日期,只需将时间设置为 0:00:00:000。

例如:

"CREATE TABLE " + Food_TABLE +"(" +
    EX_RowID + "INTEGER PRIMARY KEY AUTOINCREMENT, " +
    EX_Cattype + " TEXT NOT NULL, " +
    EX_Date + " INTEGER NOT NULL," +
    EX_Price + " INTEGER NOT NULL," +
    EX_Type + " TEXT NOT NULL UNIQUE );"

private static String dateOnly(java.util.Date d) {
    Calendar cal = Calendar.getInstance(); // locale-specific
    cal.setTime(d);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    return Long.toString(cal.getTimeInMillis());
}

public Cursor CstmRpot(java.util.Date fd, java.util.Date td) {
    // TODO Auto-generated method stub
    String[] columns = new String[]{EX_RowID,EX_Cattype, EX_Date, EX_Price, EX_Type };
    Cursor c= ourdatabase.query(Food_TABLE, columns, EX_Date + " > " + dateOnly (fd) + " AND " + EX_Date + " < " + dateOnly(td), null, null, null, null);
    if (c != null) {
        c.moveToFirst();
    }
    return c;
}

如果您不使用不同的时区,则可以优化 dateOnly(java.util.Date d)。 当然你也可以使用JODA-time。

2。将您的日期保存为TEXT

如果您选择此方法,则比较日期列的查询会慢一些,但数据库中的条目是人类可读的,而方法 1 并非如此。 TEXT-columns 默认以BINARY 排序,这意味着memcmp() 用于比较值并确定哪个值更大或值是否相等。 (记住x BETWEEN a AND b 表示x &lt;= a AND x &gt;= b。) 你可以使用memcmp()这个函数检查memcmp()的工作。

为确保您获得正确的结果,您必须确保以下几点:

  1. 数据库中的所有日期值都必须具有相同的文本长度。
  2. 数据库中的所有日期值都必须采用相同的格式。较大的日期部分(年)必须在较小的日期部分(月)之前。
  3. 查询中日期值的所有参数也必须遵循这些规则。

可能的日期格式如下所示:yyyy-MM-dd(例如2014-02-042000-12-24)。

建议

  • 使用android.widget.DatePicker 而不是Edittext 获取日期作为输入。
  • 永远不要在查询中直接使用从用户输入中获得的任何文本,而是在之前验证它们(参见sql-injection)。
  • 阅读一些有关如何比较字符串的文章。

【讨论】:

  • 我喜欢您的代码先生,但您的 dateOnly() 方法我无法理解
  • 它结合了三个功能: 1. 从java.util.Date 截断时间,使其仅为日期 2. 将其转换为自 1.1.1970 以来的毫秒数。 3.将其转换为String,这是创建语句所需的。这只是如何在 sqlite 中存储日期的一个示例。关于排序字符串的其他答案也是正确的,根据您的确切需求,我会使用一种或另一种解决方案,或者只是将日期表示为数字的另一种形式。
  • 我的 EX_Date 也是字符串类型
  • 我也使用 .get(dayofmonth)、.get(monthofyear) 和 .get(year) 方法并将它们设置为 edittext.set(year + " - " + (month + 1) + " - " + 年 ); year ,monthofyear 和 dayofmonth 是我的单独变量先生,我如何将其从字符串转换为毫秒
  • @IHateErrors 请将此代码添加到您的问题中,因为它是相关的。您必须确保年份总是有 4 位数字,而月份和日期总是有两位数字。
【解决方案2】:

试试SELECT * FROM "your table" WHERE date BETWEEN "from date" AND "to date";

【讨论】:

    【解决方案3】:

    您需要存储 yyyy-mm-dd 的日期通知,然后使用此方法只需调用 getWeekData(start_date, end_date);

    public Object getWeekData(String start_date, String end_date) {
            if (!mDataBase.isOpen())
                openDataBase();
    
            Object data = new Object ();
            // Select All Query
            String query = (String) ("Select * from " + TBL_NAME 
                    + " where " + (COL_DATE + " between '" + start_date + "' AND '" + end_date + "'"));
            Cursor cursor = mDataBase.rawQuery(query, null);
            // looping through all rows and adding to list
    
            if (cursor.moveToFirst()) {
                do {
                    //get data over here
                } while (cursor.moveToNext());
            }
    
            // closing connection
            cursor.close();
            close();
            return data;
        }
    

    【讨论】:

    • 我像你一样应用我的方法,但我的数据也超出了我的范围
    【解决方案4】:

    对于这个问题,我们有两个解决方案

    一个是我们需要将日期和时间转换为毫秒,并在

    中取long数据类型

    Sqllite 数据库和保存值(转换的日期和时间)。以及像“SELECT

    ”这样的写查询

    data, start_date, end_date from tablename WHERE start_date > end_date"。

    第二种方法是您需要以字符串格式保存开始和结束日期+时间(yyy-MM-dd HH:mm:ss)

    在Sqllite数据库中,需要这样查询,

    "SELECT datetime_start,datetime_end FROM tablename WHERE(( DATETIME(atetime_start) >=

    DATETIME("+"'"+entry_start_time+"'"+")"+" AND DATETIME(datetime_end)

    ("+"'"+entry_end_time+"'"+")); .

    【讨论】:

    • 我只有一个日期列,我将它定义为数据库中的一个字符串,并且当用户单击 edittext 时我从日期选择器获取数据,它包含三个变量,我不需要时间我只关注日期
    • 当我将列作为字符串离开时,接下来我该怎么做
    • 您需要维护两列开始和结束日期。然后只有你可以查询数据库。否则您需要编写一个简单的逻辑,例如,首先您需要从 db 获取所有数据,然后您需要使用代码(如果条件)进行过滤
    猜你喜欢
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多