2013-02-12 11 views
14

İlk defa SQLite kullanıyorum ve istisna işlemlerini öğrenmeye çalışıyorum, bu yüzden test uygulamamdaki bir ekleme hatasını zorluyorum. Özel durum oluşur ve Eclipse LogCat çıktı penceresine yazıldığını görüyorum. Ancak bu kodda yakalanmaz. Doğru istisna türünü kullandığınızdan emin olmak için burada başka sorular gördüm ve bu hakkın olduğunu düşünüyorum. Ne eksik olduğum hakkında bir fikrin var mı? benim ana aktivitede aşağıdaki açıklamada, Neden istisnacı işleyicim Android SQLite hatası mı yakalamıyor?

, myTable uzanan bir sınıftır benimkinin AbstractDbAdapter ( SQLiteOpenHelper genişleten bir sınıf DatabaseHelper sahip olan).

try { 
    myTable.create("dupkey"); 
} 
catch (android.database.sqlite.SQLiteConstraintException e) { 
    Log.e(TAG, "SQLiteConstraintException:" + e.getMessage()); 
} 
catch (android.database.sqlite.SQLiteException e) { 
    Log.e(TAG, "SQLiteException:" + e.getMessage()); 
} 
catch (Exception e) { 
    Log.e(TAG, "Exception:" + e.getMessage()); 
} 

Örnek yığın izlemesi:

Error inserting id="dupkey" last_seen_ts=1360624732 first_seen_ts=1360624732 android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed 
    at android.database.sqlite.SQLiteStatement.native_execute(Native Method) 
    at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:61) 
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1582) 
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1426) 
    at com.myCompany.testApp.myTable_DbAdapter.create(myTable_DbAdapter.java:51) 

myTable ve AbstractDbAdapter sınıfları

 
public class myTable_DbAdapter extends AbstractDbAdapter { 

    private static final String DATABASE_TABLE = "myTable"; 

    // column names -- keys for ContentValues() 
    public static final String KEY_ID = "id"; 
    public static final String KEY_FIRST_SEEN = "first_seen_ts"; 
    public static final String KEY_LAST_SEEN = "last_seen_ts"; 

    public myTable_DbAdapter(Context ctx) { 
     super(ctx); 
    } 

    public long create(String id) { 
     long firstSeen = System.currentTimeMillis()/1000; // SQLite timestamps are in seconds 

     ContentValues args = new ContentValues(); 
     args.put(KEY_ID, id); 
     args.put(KEY_FIRST_SEEN, firstSeen); 
     args.put(KEY_LAST_SEEN, firstSeen); // defaults to firstSeen for a new entry 

     return mDb.insert(DATABASE_TABLE, null, args); 
    } 
} 

public abstract class AbstractDbAdapter { 

    protected static final String TAG = "AbstractDbAdapter"; 

    protected DatabaseHelper mDbHelper = null; 
    protected SQLiteDatabase mDb = null; 

    protected static final String TABLE_CREATE_MYTABLE = 
     "create table myTable (" + 
     " id text primary key not null" + 
     ", first_seen_ts integer not null" + 
     ", last_seen_ts integer not null" + 
     ");"; 

    protected static final String DATABASE_NAME = "myDB"; 
    protected static final int DATABASE_VERSION = 1; 

    protected final Context mCtx; 

    protected static class DatabaseHelper extends SQLiteOpenHelper { 

     DatabaseHelper(Context context) { 
      super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 
      // Note: SQLite requires one execSQL per table 
      db.execSQL(TABLE_CREATE_MYTABLE); 
     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
      Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which destroys existing data."); 
      db.execSQL("DROP TABLE IF EXISTS myTable"); 
      onCreate(db); 
     } 
    } 

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

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

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

} 
+0

http://stackoverflow.com/questions/4499201/sqliteconstraintexception-error-code-19-constraint-failed – Geros

+0

Lütfen "myTable_DbAdapter.create()" kodunu yazınız ve 51. satırın yerini belirtiniz. Ayrıca, verdiğiniz kodu hangi sınıf ve yöntemde içerir? –

+0

@ Code-Guru: myTable sınıfını ekledim, satır 51, create() yöntemidir (bu soruyu basitleştirmek için bazı şeyleri kaldırdığım için, yığın izlemeye tam olarak uymayacaktır). – Alan

cevap

21

burada yanıt bulundu: SQLiteConstraintException not caught

SQLiteDatabase.insert() metodu doesn Bir istisna atmayın. oh d'!

Benim gibi diğer SQLite haberleri için, veritabanına eklerken istisnalar yakalamak istiyorsanız, SQLite.insertOrThrow() yöntemini kullanın. Sonra yakalayıp tutabileceğiniz bir istisna atar.

+1

Onaylandı: myTable_DbAdapter sınıfını insertOrThrow() işlevini kullanarak değiştirerek, şimdi test uygulamamda yakalanabilir hatalar alıyorum ve LogCat çıkışında yalnızca bir satır görüyorum "SQLiteConstraintException: hata kodu 19: kısıtlama başarısız" yerine tam yığın izlemesi. – Alan

+0

Android uygulamanızda veritabanını açtıktan hemen sonra aşağıdaki kodu eklemeyi unutmayın: db.execSQL ("PRAGMA foreign_keys = ON"); Bu, ON DELETE CASCADE'ın düzgün çalışması için gerekli olan yabancı anahtarlar için desteği açar. – lidox

+0

Ben tepki-yerel olarak sqlite kullanıyorum (https://github.com/andpor/react-native-sqlite-storage). Aynı şeyi nasıl ele alabilirim? Ben benzer bir yöntem –