마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 DB(SQLite) 관련 질문

0 추천

안녕하세요. DB관련해서 질문드립니다.

 

테이블을 시간단위로 관리하고자 합니다.

그래서 테이블명을 "테이블명+시간" 으로 생성하고자 getCurrentTime()메소드를 만들었고,

테이블명이 들어가는 곳엔 +currentTime을 해서 테이블을 생성하고 접근하도록 작성하였습니다.

그런데, 제 의도와는 다르게 에러가 나네요...

에러부분도 함께 첨부합니다.

어디게 잘못된것일까요?...

답변 부탁드립니다.

------------------------------------------------------------------ 코드 시작 -----------------------------------------------

package com.example.appcounter;
 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
 
public class DatabaseAppCounter {
    private static final String LOG_NAME = DatabaseAppCounter.class.getSimpleName();
 
    public static final String TableName = "AppCounter";
    public static String currentTime = null;        // 테이블명 뒤에 현재 시간을 붙임,
                                                    // 총 24개의 테이블을 생성하기 위함...
     
    public static class Column {
        public static final String IDX = "idx";
        public static final String PACKAGE_NAME = "package_name";
        public static final String EXECUTE_TIME = "execute_time";
    }
 
    public class AppInfo {
 
        private String packageName;     // 앱 이름
        private Date executeTime;       // 실행시간
        private long executeCount;      // 실행횟수
 
        public String getPackageName() {
            return packageName;
        }
 
        public void setPackageName(String packageName) {
            this.packageName = packageName;
        }
 
        public Date getExecuteTime() {
            return executeTime;
        }
 
        public void setExecuteTime(String executeTime) {
            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                this.executeTime = dateFormat.parse(executeTime);
            } catch (ParseException e) {
                Log.e(LOG_NAME, "setExecuteTime - " + e.getMessage());
            }
        }
 
        public long getExecuteCount() {
            return executeCount;
        }
 
        public void setExecuteCount(long executeCount) {
            this.executeCount = executeCount;
        }
    }
 
    private static Context mContext;
    private static SQLiteDatabase db;
    private static DatabaseHelper dbHelper;
    private static DatabaseAppCounter instance;
     
    private DatabaseAppCounter() {
         
    }
 
    public synchronized static DatabaseAppCounter getInstance(Context applicationContext) {
 
        if (instance == null) {
            instance = new DatabaseAppCounter();
            mContext = applicationContext;
            dbHelper = new DatabaseHelper(applicationContext);
            db = dbHelper.getWritableDatabase();
        }
        currentTime = getCurrentTime();                         // 현재 시간을 받아 온다.
        return instance;
    }
 
    public void insertAppInfo(String packageName) {
        db.execSQL(new StringBuilder()
                                                                                                        // 여기 수정함...
                .append("INSERT INTO " + TableName+currentTime + " VALUES ( ").append("null, ")
                .append("'" + packageName + "', ")
                .append("strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime') )")
                .toString());
    }
 
    public AppInfo getOrderByApp(String order) {
        if (order == null || "ASC".equals(order.toUpperCase()) == false
                && "DESC".equals(order.toUpperCase()) == false) {
            Log.d(LOG_NAME, "getOrderByApp - param(order) is wrong: " + order);
            return null;
        }
        Cursor cursor = db.rawQuery(
                new StringBuilder()
                        .append("SELECT " + Column.PACKAGE_NAME + "," + Column.EXECUTE_TIME)
                        .append(" FROM " + TableName+currentTime).append(" WHERE " + Column.EXECUTE_TIME + " IS NOT NULL ")     // 여기도 수정함
                        .append(" ORDER BY ")
                        .append(Column.EXECUTE_TIME).append(" " + order)
                        .append(" LIMIT 1").toString(), null);
         
        AppInfo appInfo = null;
        if (cursor.moveToNext()) {
            appInfo = new AppInfo();
            appInfo.setPackageName(cursor.getString(cursor.getColumnIndex(Column.PACKAGE_NAME)));
            appInfo.setExecuteTime(cursor.getString(cursor.getColumnIndex(Column.EXECUTE_TIME)));
        }
        return appInfo;
    }
 
    public List<AppInfo> getAppCountList() {
        List<AppInfo> appCountList = new ArrayList<AppInfo>();
 
        Cursor cursor = db.rawQuery(
                new StringBuilder()
                        .append(" SELECT " + Column.PACKAGE_NAME + ","+Column.EXECUTE_TIME+", COUNT(*) AS COUNT")
                        .append(" FROM " + TableName+currentTime)               // 여기도 수정함
                        .append(" GROUP BY " + Column.PACKAGE_NAME)
                        .append(" ORDER BY COUNT DESC").toString(), null);
 
        AppInfo appInfo = null;
        while (cursor.moveToNext()) {
            appInfo = new AppInfo();
            appInfo.setPackageName(cursor.getString(cursor.getColumnIndex(Column.PACKAGE_NAME)));
            appInfo.setExecuteCount(cursor.getLong(cursor.getColumnIndex("COUNT")));
             
            appInfo.setExecuteTime(cursor.getString(cursor.getColumnIndex(Column.EXECUTE_TIME)));
            appCountList.add(appInfo);
             
            MainActivity.packageList.add(cursor.getString(cursor.getColumnIndex(Column.PACKAGE_NAME)));
             
//          Log.d("@@package name", cursor.getString(cursor.getColumnIndex(Column.PACKAGE_NAME)));
//          Log.d("@@execute time", cursor.getString(cursor.getColumnIndex(Column.EXECUTE_TIME)));
        }
         
        return appCountList;
    }
 
    static class DatabaseHelper extends SQLiteOpenHelper {
        public DatabaseHelper(Context context) {
            super(context, "AppCounter.db", null, 1);
        }
 
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(new StringBuilder()
                    .append("CREATE TABLE " + TableName+currentTime + "(")      // 여기도 수정함
                    .append(DatabaseAppCounter.Column.IDX+ " INTEGER PRIMARY KEY AUTOINCREMENT, ")
                    .append(DatabaseAppCounter.Column.PACKAGE_NAME + " TEXT, ")
                    .append(DatabaseAppCounter.Column.EXECUTE_TIME + " TEXT) ")
                    .toString());
        }
 
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + TableName+currentTime);        // 여기도 수정함
        }
    }
     
    public static String getCurrentTime() {
        long now = System.currentTimeMillis();
        Date date = new Date(now);
        SimpleDateFormat sdfNow = new SimpleDateFormat("HH"); // 시간만 받오는 방법
        return sdfNow.format(date);
    }
     
}

---------------------------------------------- 에러메시지 -----------------------------------------------------------------

java.lang.RuntimeException: Unable to resume activity {com.example.appcounter/com.example.appcounter.MainActivity}: android.database.sqlite.SQLiteException: no such table: AppCounter23 (code 1): , while compiling: SELECT package_name,execute_time FROM AppCounter23 WHERE execute_time IS NOT NULL  ORDER BY execute_time ASC LIMIT 1

Caused by: android.database.sqlite.SQLiteException: no such table: AppCounter23 (code 1): , while compiling: SELECT package_name,execute_time FROM AppCounter23 WHERE execute_time IS NOT NULL  ORDER BY execute_time ASC LIMIT 1

 

보타 (140 포인트) 님이 2015년 4월 12일 질문

1개의 답변

0 추천
테이블을 시간단위로 만든다고 하시는데 왜 그래야 하는지 이해가 안 가네요.

일단 에러는 에러 메세지대로 AppCounter23이라는 테이블이 없어서 발생한 것입니다.

액티비티 등의 소스가 없어서 확실하지는 않지만, 테이블 생성하는 부분이 하나여서 그 시간대만 테이블을 생성하므로, 그 시간대를 넘어가면 위와 같은 현상이 재현될 것 같습니다.

위 에러메세지를 재현하자면 22:59분에 앱을 실행하고 쿼리문이 23:00에 실행된다면 저렇게 에러가 발생하겠죠. 테이블은 22를 생성했을거고, 쿼리 대상 테이블은 23이니까요.

그냥 한 테이블에 저장하고 시간대로 쿼리하는 게 훨씬 간단하지 않나요?
cc1232 (35,280 포인트) 님이 2015년 4월 13일 답변
...