2012-03-03 84 views
1

我有一个使用多个数据库的应用程序。目前,我遇到了其中一个问题。它在数据库中存储日历的事件。它SQLiteOpenHelper看起来是这样的:Android SQLiteDatabase无法插入或查询

public class PlanSQLiteHelper extends SQLiteOpenHelper { 

//The database version. 
public static final int VERSION = 1; 

//The String keys of the database name and columns. 
public static final String DB_NAME = "plans_db.sqlite"; 
public static final String PLANS_TABLE = "plans"; 
public static final String PLAN_ID = "id"; 
public static final String PLAN_NAME = "name"; 
public static final String PLAN_YEAR = "year"; 
public static final String PLAN_MONTH = "month"; 
public static final String PLAN_DAY = "day"; 
public static final String PLAN_PRIORITY = "priority"; 
public static final String PLAN_TIME = "time"; 
public static final String PLAN_END = "end"; 
public static final String SET_APPT = "set_appt"; 
public static final String PLAN_ALARM = "alarm"; 


public PlanSQLiteHelper(Context context) { 
    super(context, DB_NAME, null, VERSION); 
} 

@Override 
public void onCreate(SQLiteDatabase db) { 
    createTable(db); 
} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } 

private void createTable(SQLiteDatabase db) { 

    db.execSQL(
      "create table " + PLANS_TABLE + " (" + 
      PLAN_ID + " integer primary key autoincrement not null, " + 
      PLAN_NAME + " text, " + 
      PLAN_YEAR + " integer, " + 
      PLAN_MONTH + " integer, " + 
      PLAN_DAY + " integer, " + 
      PLAN_PRIORITY + " integer, " + 
      PLAN_TIME + " integer, " + 
      PLAN_END + " integer, " + 
      SET_APPT + " integer, " + 
      PLAN_ALARM + " integer);"); 
} 
} 

这是这个过程: 用户到一个屏幕来创建一个新的日历项(称为PlanItem)。它有一些选择,他们选择他们想要的,然后他们点击“确定”。该PlanItem制成,并传递给应用程序的应用类中的方法,它看起来像:

/** 
* Called to save a PlanItem to the SQLiteDatabase. 
* @param item = the item to save to the database. 
* @param newItem = true if the item is new, false if it exists but was edited. 
* @return true if successful, false otherwise. 
*/ 
public boolean savePlanItem(PlanItem item, boolean newItem) { 

    try { 

     //Create the ContentValues. 
     ContentValues values = new ContentValues(); 

     //Put the values in. 
     values.put(PLAN_NAME, item.getName()); 
     values.put(PLAN_YEAR, item.getYear()); 
     values.put(PLAN_MONTH, item.getMonth()); 
     values.put(PLAN_DAY, item.getDay()); 
     values.put(PLAN_TIME, item.getTime()); 
     values.put(PLAN_END, item.getEnd()); 
     values.put(SET_APPT, item.isSetAppt() ? 1 : 0); 
     values.put(PLAN_PRIORITY, item.getPriorityInt()); 
     values.put(PLAN_ALARM, item.isAlarm() ? 1 : 0); 

     if (newItem) { 

      //Put into the database. 
      long id = plansDatabase.insert(PLANS_TABLE, null, values); 

      if (id == -1) { 
       return false; 
      } 
     } 
     else { 

      //Update the database. 
      String where = String.format("%s = ?", PLAN_ID); 
      plansDatabase.update(PLANS_TABLE, values, where, new String[] { item.getId() + "" }); 
     } 

    } 
    catch (Exception e) { 
     return false; 
    } 

    //Since it succeeded, return true. 
    return true; 
} 

布尔的newitem只是告诉该方法,如果该项目被创建或编辑。我的问题在于创作。如您所见,它使用SQLiteDatabase.insert()方法。我甚至可以获取新行的id并对-1进行测试(如果根据Android文档发现错误,则返回-1)。即使如此,该方法返回true,这意味着它保存正确。 然后一旦保存,允许用户创建项目的活动就结束并返回到显示它的活动。在onResume()中,它调用Application类来获取当天的PlanItems。它看起来像:

/** 
* Called to get the agenda items for a particular day. 
* @param date = the date to get agenda items for. 
* @return the ArrayList of PlanItems for the day. 
*/ 
public ArrayList<PlanItem> getDailyAgenda(Date d) { 

    //Make a new date. 
    Date date = new Date(d.getDay(), d.getMonth(), d.getYear()); 

    //Create the ArrayList. 
    ArrayList<PlanItem> items = new ArrayList<PlanItem>(); 

    //Set up a query. 
    Cursor cursor = plansDatabase.query(PLANS_TABLE, new String[] {PLAN_ID, PLAN_NAME, PLAN_YEAR, 
      PLAN_MONTH, PLAN_DAY, PLAN_PRIORITY, PLAN_TIME, PLAN_END, SET_APPT, PLAN_ALARM}, 
      String.format(" %s = ? AND %s = ? AND %s = ? ", PLAN_YEAR, PLAN_MONTH, PLAN_DAY), 
      new String[] {String.valueOf(date.getYear()), String.valueOf(date.getMonth()), 
      String.valueOf(date.getDay())}, null, null, null); 

    //Move the cursor to the first position. 
    cursor.moveToFirst(); 

    //If there are items... 
    if (!cursor.isAfterLast()) { 

     //Initialize variables. 
     long id; 
     String name; 
     int year, month, day, time, end, priority; 
     boolean setAppt, alarm; 
     PlanItem item; 


     //Go through the database and get everything. 
     do { 

      //Get the values. 
      id = cursor.getLong(0); 
      name = cursor.getString(1); 
      year = cursor.getInt(2); 
      month = cursor.getInt(3); 
      day = cursor.getInt(4); 
      priority = cursor.getInt(5); 
      time = cursor.getInt(6); 
      end = cursor.getInt(7); 
      setAppt = cursor.getInt(8) == 1; 
      alarm = cursor.getInt(9) == 1; 

      //Create a PlanItem and add it to the ArrayList. 
      item = new PlanItem(id, name, year, month, day, 
        priority, time, end, setAppt, alarm); 
      items.add(item); 

     } while (cursor.moveToNext()); 
    } 

    //Close the cursor. 
    cursor.close(); 

    //Return the items. 
    return items; 
} 

对象日期是我自己的对象,而不是Java对象。它只包含我需要的方法。

我已经在调试器中检查并重新检查了查询。它遵循SQLite规则。但是,即使在当天创建新项目之后,它也不会从数据库中提取任何内容。它到达return items;行并返回一个空的ArrayList。我移动了周围的日子,看看这个物品是否存储在错误的日子里,但事实并非如此。我还检查了哪些日期,月份和年份正在插入到数据库中。他们是正确的。

我来到这里来stackoverflow并找不到答案。

我无法弄清楚我的生活。请帮忙。

由于这是我的第一个问题,所以如何改善我的问题的任何意见,表示赞赏。

回答

0

好的,这是交易。我现在觉得很愚蠢。问题已经解决了。这是行不通的原因是,在某些地方,我已经在MY OWN Date对象构造函数中将年份和日期颠倒过来。将年,月和日直接放入查询中(而不是问号)后,我发现了这一点。无论如何,我希望这是一个很好的学习经历。

0

您应该尝试在savePlanItem()函数中记录异常,以确保插入完成。

而只是一个问题,你在哪里打开这些函数中的数据库?

+0

我在应用程序类的onCreate()方法中打开它。另外,我通过检查返回的id为-1来检查savePlanItem()方法中的错误(Android文档说当发生错误时返回-1)。也就是说,我会添加日志,只是为了看看有什么不同 – 2012-03-05 16:44:09

+0

我会投票你的答案,但我没有足够的声誉。感谢您的帮助。如果你想知道我为什么遇到了问题,请查看问题页面;这很尴尬。谢谢你的帮助! – 2012-03-06 00:47:00