2014-05-18 5 views
0

위시리스트 앱에서 사용하고있는 SQLite 데이터베이스 테이블이 있습니다. 나는 데이터베이스에서 구입 한 아이템의 이력을 저장할 수 있기를 원한다. 위시리스트의 각 항목에는 위시리스트의 항목이 구입되었음을 나타 내기 위해 사용자가 클릭 할 수있는 "구입 한"체크 박스가있는 상세보기가 있습니다. 그런 다음 사용자가 누를 수있는 옵션 메뉴에서 데이터베이스의 항목으로 채워지는 목록 뷰를 가져 오는 별도의 "기록"옵션이 있습니다.기본 키가 아닌 텍스트를 기반으로 테이블에서 행을 삭제하는 방법은 무엇입니까?

세부보기에서 "구입하다"확인란을 선택하면 이름을 사용하여 데이터베이스에 항목을 추가하는 확인란의 청취자를 얻을 수 있었고 이름이 데이터베이스의 기록 목록보기에 표시됩니다. 그러나 상자를 선택 해제하면 데이터베이스에서 행을 삭제하는 데 사용하려고하는 sql 명령이 작동하지 않습니다. 이제는 아무 것도하지 않고 오류를내는 데 사용됩니다. 나는 도우미 클래스와 코드의 일부를 포함시켜 주 코드에서 이름을 사용하여 항목을 추가하고 삭제합니다. ID 번호를 검색하는 대신 직접 항목 이름을 사용하여 삭제 한 다음 삭제하려고합니다. 나는 중복을 삭제하는 것에 대해 걱정하지 않기 때문에 직접 이름을 사용하고 싶습니다. 나는 다른 게시물과 여러 참고 문헌을 읽으려고했지만 내가 무엇을 놓쳤는 지 알 수 없다.

ps. delete 문에서 sql을 사용하지 않고 " '"시도했지만 오류가 발생했습니다. 이렇게하면 나는 아무것도 얻지 못합니다. 단지보기에서 제거하지 않습니다. DBHelper

에서

코드

public class DBHelper extends SQLiteOpenHelper { 

private static final String DB_NAME = "goodthings2.db"; 
private static final int DB_VERSION = 2; 

public static final String TABLE_THINGS = "things"; 
public static final String C_ID = "_id"; 
public static final String C_TITLE = "title"; 
public static final String C_PRICE = "price"; 
public static final String C_DATE = "date"; 

public DBHelper(Context context){ 
    super(context, DB_NAME, null, DB_VERSION); 
} 

@Override 
public void onCreate(SQLiteDatabase db) { 

    final String sqlCreateTablePeople = 
      "CREATE TABLE " + TABLE_THINGS + 
      "(" + C_ID + " integer primary key autoincrement, " 
       + C_TITLE + " text not null);"; 

    db.execSQL(sqlCreateTablePeople); 

} 

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

    final String sqlDropTablePeople = "DROP TABLE IF EXISTS " + TABLE_THINGS + 
";"; 
    db.execSQL(sqlDropTablePeople); 
    onCreate(db); 

} 

} 

위시리스트 항목 상세 뷰의 조각의 코드 섹션 : 조건 매개 변수가 제대로 구축되지

mPurchasedCheckBox.setOnCheckedChangeListener(
     new OnCheckedChangeListener(){ 
      public void onCheckedChanged(CompoundButton buttonView, 
boolean isChecked){ 

      mThing.setPurchased(isChecked); 
      //Toast.makeText(getActivity(), 
mThing.getTitle().toString(), Toast.LENGTH_LONG).show(); 

      //String name = mThing.getTitle().toString(); 

      if(isChecked == true){ 
       Toast.makeText(getActivity(), "isChecked = true", 
Toast.LENGTH_LONG).show(); 

       // add the new data to the db 
       DBHelper helper = new DBHelper(getActivity()); 
       SQLiteDatabase db = helper.getWritableDatabase(); 
       ContentValues cv = new ContentValues(); 
       cv.put(DBHelper.C_TITLE, 
mThing.getTitle().toString()); 
       //cv.put(DBHelper.C_PRICE, 
mThing.getPrice().toString()); 
       //cv.put(DBHelper.C_DATE, 
mThing.getDate().toString()); 
       //cv.put(DBHelper.C_ID, mThing.getId().toString()); 
       db.insert(DBHelper.TABLE_THINGS, null, cv); 
       db.close(); 


      }else{ 

       Toast.makeText(getActivity(), "isChecked = false", 
Toast.LENGTH_LONG).show(); 

       /*SQLiteDatabase db = new 
DBHelper(getActivity()).getWritableDatabase(); 

       int rowsAffected = -1; 

       rowsAffected = db.delete(DBHelper.TABLE_THINGS, 
DBHelper.C_ID + " = " + mThing.getId().toString(), null); 

       Toast.makeText(getActivity(), "rowsAffected = " + 
rowsAffected, Toast.LENGTH_LONG).show(); 

       db.close();*/ 

       DBHelper helper = new DBHelper(getActivity()); 

       SQLiteDatabase db = helper.getWritableDatabase(); 

       db.execSQL("delete from " + DBHelper.TABLE_THINGS + 
" where " + DBHelper.C_TITLE + " = " + " ' " + mThing.getTitle().toString() + " ' "); 

      } 
     } 

    }); 
+0

예 : "내 제목"! = "내 제목"? –

+0

'ListView'를 채우는 데 사용중인 SQL 쿼리 또는 어댑터 유형을 표시하지 않습니다. 'SELECT * ...'질의와'SimpleCursorAdapter'를 사용한다면 분명히'ListView' 행에 'ID'를 표시 할 필요는 없지만 각각의'Cursor'에서 접근 할 수 있습니다 열. 개인적으로 나는 일치하는 텍스트 문자열에 근거를 두는 것보다 고유 한 'id'로 작업하고 싶습니다. 누군가 두 개 이상의 동일한 항목을 위시리스트에 추가하고 오직 하나만 구입 한 경우 어떻게해야합니까? 텍스트 일치로 삭제하면 목록에서 모두 삭제됩니다. – Squonk

답변

1

:

DBHelper.C_TITLE + " = " + " ' " + mThing.getTitle().toString() + " ' "); 

공간 따옴표 사이에 매개 변수의 처음과 끝에 여분의 공백이 생깁니다 (예 : '제목'대신 '제목'이 표시되므로 삭제할 레코드를 찾을 수 없습니다.

제안 : 이와 같이 사용자 지정 SQL 문을 작성하여 행을 삭제하지 말고 대신 SQLiteDatabase.delete() 메서드를 사용하십시오. 필요한 경우 매개 변수를 올바르게 이스케이프 처리합니다. 그렇지 않으면 앱이 SQL injection에 노출됩니다. 추가 보너스로 결과는 삭제 된 레코드 수를 알려줍니다.

관련 문제