2013-03-29 1 views
0

오류 : column _id does not exists이 표시되지만 데이터베이스의 열 (기본 키로 설정 됨)이 외부 SD 폴더에 있습니다. 활동의 초기로드시 데이터베이스에 포함 된 값을 반환하려고하지만 커서가 아무 것도 반환하지 않는 것처럼 보입니다.SimpleCursorAdapter가 외부 sqlite 데이터베이스를로드하지 않습니다. "_id"오류

public class ComponentsDbAdapter { 

    public static final String COLUMN_ID = "_id"; 
    public static final String COLUMN_SUBSTRUCTURE = "substructure"; 
    public static final String COLUMN_TYPE = "type"; 
    public static final String COLUMN_ORDERNUM = "ordernum"; 
    public static final String COLUMN_INSTALLATION = "installation"; 
    private static final String TAG = "ComponentsDbAdapter"; 
    private DatabaseHelper mDbHelper; 
    private SQLiteDatabase mDb; 
    private static final String DATABASE_PATH = Environment.getExternalStorageDirectory().getAbsoluteFile()+ "/DATABASE_BACKUP/IMPORTED/"; 
    private static final String DATABASE_NAME = "android.db"; 
    private static final String TABLE_NAME = "TAB_WORKSCPE"; 
    private static final int DATABASE_VERSION = 1; 
    private final Context mCtx; 


    public ComponentsDbAdapter open() throws SQLException { 
    mDbHelper = new DatabaseHelper(mCtx); 
    mDb = mDbHelper.getWritableDatabase(); 
    return this; 
    } 

    private static class DatabaseHelper extends SQLiteOpenHelper { 
    DatabaseHelper(Context context) { 
     super(context, DATABASE_PATH+DATABASE_NAME, null, DATABASE_VERSION); 
    } 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.query(TABLE_NAME, new String[] {COLUMN_ID, COLUMN_SUBSTRUCTURE, COLUMN_TYPE, COLUMN_ORDERNUM, COLUMN_INSTALLATION}, null, null, null, null, null); 
    } 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
     onCreate(db); 
    } 
    } 

    public ComponentsDbAdapter(Context ctx) { 
    this.mCtx = ctx; 
    } 

    public void close() { 
    if (mDbHelper != null) { 
     mDbHelper.close(); 
    } 
} 

    public Cursor fetchComponentsByName(String inputText) throws SQLException { 
    Log.w(TAG, inputText); 
    Cursor mCursor = null; 
    if (inputText == null || inputText.length() == 0) { 
     mCursor = mDb.query(TABLE_NAME, new String[] {COLUMN_ID, COLUMN_SUBSTRUCTURE, COLUMN_TYPE, COLUMN_ORDERNUM, COLUMN_INSTALLATION}, null, null, null, null, null); 
} else { 
    mCursor = mDb.query(true, TABLE_NAME, new String[] {COLUMN_ID, COLUMN_SUBSTRUCTURE, COLUMN_TYPE, COLUMN_ORDERNUM, COLUMN_INSTALLATION}, COLUMN_TYPE + " like '%" + inputText + "%'", null, null, null, null, null); 
} 
    if (mCursor != null) { 
     mCursor.moveToFirst(); 
    } 
    return mCursor; 
} 

public Cursor fetchAllComponents() { 
    Cursor mCursor = mDb.query(TABLE_NAME, new String[] {COLUMN_ID, COLUMN_SUBSTRUCTURE, COLUMN_TYPE, COLUMN_ORDERNUM, COLUMN_INSTALLATION}, null, null, null, null, null); 
    if (mCursor != null) { 
     mCursor.moveToFirst(); 
    } 
    return mCursor; 
    } 
} 





public class AndroidListViewCursorAdaptorActivity extends Activity { 

private ComponentsDbAdapter dbHelper; 
private SimpleCursorAdapter dataAdapter; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    dbHelper = new ComponentsDbAdapter(this); 
    dbHelper.open(); 

    //Generate ListView from SQLite Database 
    displayListView(); 
} 

private void displayListView() { 
    Cursor cursor = dbHelper.fetchAllComponents(); 

    // The desired columns to be bound 
    String[] columns = new String[] { 
     ComponentsDbAdapter.COLUMN_SUBSTRUCTURE, 
     ComponentsDbAdapter.COLUMN_TYPE, 
     ComponentsDbAdapter.COLUMN_ORDERNUM, 
     ComponentsDbAdapter.COLUMN_INSTALLATION 
    }; 

    // the XML defined views which the data will be bound to 
    int[] to = new int[] { 
     R.id.inst, 
     R.id.subdt, 
     R.id.type, 
     R.id.ordernum, 
    }; 

    // create the adapter using the cursor pointing to the desired data 
    //as well as the layout information 
    dataAdapter = new SimpleCursorAdapter(
     this, 
     R.layout.country_info, 
     cursor, 
     columns, 
     to, 
     0); 

    ListView listView = (ListView) findViewById(R.id.listView1); 
    // Assign adapter to ListView 
    listView.setAdapter(dataAdapter); 


    listView.setOnItemClickListener(new OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> listView, View view, 
      int position, long id) { 
      // Get the cursor, positioned to the corresponding row in the result set 
      Cursor cursor = (Cursor) listView.getItemAtPosition(position); 

      // Get the state's capital from this row in the database. 
      String compSubdt = cursor.getString(cursor.getColumnIndexOrThrow("subdt")); 
      Toast.makeText(getApplicationContext(), compSubdt, Toast.LENGTH_SHORT).show(); 
     } 
    }); 

    EditText myFilter = (EditText) findViewById(R.id.myFilter); 
    myFilter.addTextChangedListener(new TextWatcher() { 

     public void afterTextChanged(Editable s) { 
     } 

     public void beforeTextChanged(CharSequence s, int start,int count, int after) { 
     } 

     public void onTextChanged(CharSequence s, int start,int before, int count) { 
      dataAdapter.getFilter().filter(s.toString()); 
     } 
    }); 

    dataAdapter.setFilterQueryProvider(new FilterQueryProvider() { 
     public Cursor runQuery(CharSequence constraint) { 
      return dbHelper.fetchComponentsByName(constraint.toString()); 
     } 
    }); 
} 
} 
+0

'CREATE TABLE ...'을 볼 수 없습니다. 어때''db.execSQL ("CREATE TABLE ...")'당신'onCreate()'? – Trinimon

+0

또한 코드를 복사 한 튜토리얼을 인용해야합니다 : vogella.com의 [AndroidSQLite] (http://www.vogella.com/articles/AndroidSQLite/article.html) – dcow

+0

죄송합니다. 자습서에 대한 언급을 언급해야합니다. : http://www.mysamplecode.com/2012/07/android-listview-cursoradapter-sqlite.html 데이터가 이미 존재하므로 CREATE TABLE을 놓친다는 것을 알고 있습니다. 다른 커서가 필요합니까? – user2224135

답변

0

좋아, 이것은 거의 일주일이 걸렸지 만 많은 스트레스가 있지만 여기에는 해결책이 있습니다. 나는 자습서의 많은 통해 이동하기 시작이 한 일을 가지고 :

http://www.mysamplecode.com/2012/11/android-database-content-provider.html

나는 가상 장치에서 데이터베이스를 추출하여 수동으로 더 많은 데이터를 추가했다. 그런 다음 데이터베이스를 내 장치 폴더의 원하는 폴더에 복사합니다 (데이터베이스 일관성/열이 정확히 일치하는지 확인하기 만하면됩니다).

public class MyDatabaseHelper extends SQLiteOpenHelper { 

    private static final String DATABASE_PATH = Environment.getExternalStorageDirectory().getAbsoluteFile()+ "/MYFOLDER/"; 
    private static final String DATABASE_NAME = "TheWorld.db"; 
    private static final int DATABASE_VERSION = 1; 

    MyDatabaseHelper(Context context) { 
     super(context, DATABASE_PATH+DATABASE_NAME, null, DATABASE_VERSION); 
    } 

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

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

이 매니페스트에 권한을 추가하는 것을 잊지 마세요 :

<uses-permission 
    android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

를 완료 한 후 다음과 같이 MyDatabaseHelper 클래스를 변경! 위의 게시물을 읽으면 Kirks의 조언을 바탕으로 대답이 나와 있으므로 추천 링크를 읽는 것이 도움이됩니다. 내 데이터베이스 구조가 잘못되었을 때를 대비하여 더 많은 테스트를 수행해야합니다.

0

코드에서 아직 테이블을 만들지 않았으므로 열을 찾을 수 없습니다.

이 방법은 onCreate 메서드에서 쿼리를 만들어 테이블을 만듭니다. 귀하의 코드에서 당신은 선택보다는 선택을하고있는 것처럼 보입니다.

private static final String TABLE_CREATE = "create table " 
    + TABLE_NAME 
    + "(" 
    + COLUMN_ID + " integer primary key autoincrement, " 
    + COLUMN_TYPE + " text not null default '', " 
    + COLUMN_ORDERNUM + " integer not null default 0, " 
    + COLUMN_INSTALLATION + " integer not null default 0, " 
    + COLUMN_SUBSTRUCTURE + " text not null default ''" 
    + ");"; 

@Override 
public void onCreate(SQLiteDatabase database) { 
    database.execSQL(TABLE_CREATE); 
} 

외부 저장소에 저장하려면 getDatabasePath(...)을 덮어 써야합니다. 비슷한 솔루션은 나는 그것이 ContextWrapper의 구성원이기 때문에 당신이 당신의 Application 클래스와이를 오버라이드 (override) 할 수 있습니다 믿고 여기 https://stackoverflow.com/a/8385537/935779

@Override 
public File getDatabasePath(String name) { 
    // reference where you would like the file to be here. 
    File result = new File(getExternalFilesDir(null), name); 
    return result; 
} 

입니다.

getDatabaseFile(...)openOrCreateDatabase(...) 안에 사용되어 위치를 결정합니다.

또는 openOrCreateDatabase(...)을 무시하고 파일 위치를 설정할 수도 있습니다.

+0

나는 그것이 데이터베이스를 만들 것이라고는 생각하지 않습니다. sqlite create table 문을 통해 테이블 ​​구조를 정의해야합니다. 위에 링크 된 튜토리얼에는 create 문이 있지만 코드의 버전은 그렇지 않습니다. – Kirk

+0

자습서를 수정하여 목록을로드하면 데이터도로드됩니다. 이제 CREATE TABLE을 사용하는 코드가 제대로 작동합니다. "데이터베이스가 종료되지 않고/DATA/DATA/...에서 데이터를 만들면 편집 페이지 (활동)를 통해 데이터가 추가됩니다. +로드가 잘됩니다. 또한. 그러나 외부 데이터베이스에 대한 경로를 지정하면이를 읽지 못하는 것처럼 보입니다. 매니페스트에 android.permission.WRITE_EXTERNAL_STORAGE를 포함하지 않으면 쓰기 권한이 없다고 말합니다. 따라서 연결하려고 시도합니다. – user2224135

+0

메서드를 재정 의하여 데이터베이스 파일 위치를 변경해야합니다. 내 대답을 업데이트했습니다 – Kirk

0

나는 데이터베이스의 위치를 ​​변경하거나 지정할 수 있다고 생각하지 않는다. 경로를 종료하고 외부 저장소에 저장하지 마세요. 안드로이드가 경로를 결정하게하십시오.