Android下的SQLite:约束失败,插入/替换空数据库[解决]
问题描述:
我有这个问题,在一个完全空的数据库/表上我的关键约束似乎失败,我不知道为什么。我已经用adb导出数据库,并用sqliteman打开它;它仍然是空的。Android下的SQLite:约束失败,插入/替换空数据库[解决]
这是我的代码:
public class DatabaseAdapterSystem extends SQLiteOpenHelper {
private Context context;
private static final int DATABASE_VERSION = 20;
private static final String DATABASE_NAME = "databaseSystem";
public DatabaseAdapterSystem(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
@Override
public void onOpen(SQLiteDatabase db) {
Log.d(getClass().getSimpleName(), "isReadOnly: " + db.isReadOnly());
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.beginTransaction();
db.execSQL(
"CREATE TABLE \"accounts\" (" +
"\"userId\" INTEGER PRIMARY KEY NOT NULL, " +
"\"nickname\" TEXT NOT NULL, " +
"\"password\" TEXT NOT NULL, " +
"\"profileImageFileName\" TEXT NOT NULL " +
")"
);
db.setTransactionSuccessful();
}
finally {
db.endTransaction();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Until yet no need
}
// -------------------------------------------------------------------------
public synchronized BackendAccountList getAccounts() {
Log.d(getClass().getSimpleName(), "DatabaseAdapterSystem::getAccounts has been called");
BackendAccountList result = new BackendAccountList();
SQLiteDatabase db = null;
Cursor resultSet = null;
try {
db = this.getReadableDatabase();
resultSet = db.query(
"accounts",
new String[] {"userId", "nickname", "password", "profileImageFileName"}, // Columns
null, // Selection
null, // SelectionArgs
null, // GroupBy
null, // Having
"userId asc"
);
if (resultSet != null) {
int colUserId = resultSet.getColumnIndex("userId");
int colNickname = resultSet.getColumnIndex("nickname");
int colPassword = resultSet.getColumnIndex("password");
int colProfileImageFileName = resultSet.getColumnIndex("profileImageFileName");
if (resultSet.moveToFirst()) {
do {
result.add(new BackendAccount(
resultSet.getInt(colUserId),
resultSet.getString(colNickname),
resultSet.getString(colPassword),
resultSet.getString(colProfileImageFileName)
));
} while (resultSet.moveToNext());
}
}
}
finally {
if (resultSet != null) {
resultSet.close();
}
if (db != null) {
db.close();
}
}
return result;
}
public synchronized BackendAccountList putAccount(BackendAccount account) {
Log.d(getClass().getSimpleName(), "DatabaseAdapterSystem::putAccount has been called");
BackendAccountList result = new BackendAccountList();
SQLiteDatabase db = null;
try {
db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("userId", account.getUserId());
cv.put("nickname", account.getUsername());
cv.put("password", account.getPassword());
cv.put("profileImageFileName", account.getProfileImage());
db.insertOrThrow("accounts", null, cv);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (db != null) {
db.close();
}
}
return result;
}
}
应用程序被加载后,getAccounts被调用和返回BackendAccounts的列表。 成功通信后,可能会调用putAccount来在数据库中存储新帐户。
我已经试过replaceOrThrow,但即使失败上的约束(误差19)
//编辑:堆栈跟踪
04-16 10:47:05.910: W/System.err(13130): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
04-16 10:47:05.910: W/System.err(13130): at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
04-16 10:47:05.910: W/System.err(13130): at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:66)
04-16 10:47:05.910: W/System.err(13130): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1426)
04-16 10:47:05.910: W/System.err(13130): at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1308)
04-16 10:47:05.910: W/System.err(13130): at com.jappy.service.DatabaseAdapterSystem.putAccount(DatabaseAdapterSystem.java:183)
04-16 10:47:05.910: W/System.err(13130): at com.jappy.service.JappyService$1.handleMessage(JappyService.java:60)
04-16 10:47:05.910: W/System.err(13130): at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 10:47:05.910: W/System.err(13130): at android.os.Looper.loop(Looper.java:123)
04-16 10:47:05.920: W/System.err(13130): at android.app.ActivityThread.main(ActivityThread.java:4363)
04-16 10:47:05.920: W/System.err(13130): at java.lang.reflect.Method.invokeNative(Native Method)
04-16 10:47:05.920: W/System.err(13130): at java.lang.reflect.Method.invoke(Method.java:521)
04-16 10:47:05.920: W/System.err(13130): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
04-16 10:47:05.920: W/System.err(13130): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-16 10:47:05.920: W/System.err(13130): at dalvik.system.NativeStart.main(Native Method)
//编辑 其中一列包含NULL( profileImageFilename)。这就是sqlite抛出这个消息的原因。 问题解决了。
答
如果违反了某个约束条件,则会抛出SQLiteConstraintException
。在你的情况下,所有四个字段都被限制为非null
。所以,错误是由于试图将一个null
值插入到其中一个字段中而导致的。添加一些日志记录来找出它是哪一个。
什么是错误?发布堆栈跟踪。 – 2012-04-16 08:57:27
那么,四个字段之一是'null'。添加一些日志记录来找出它是哪一个。 – 2012-04-16 09:08:18
太棒了。不知道在这种情况下,sqlite会抛出错误。谢谢。 – pmedia 2012-04-16 09:12:19